[
  {
    "path": ".github/FUNDING.yml",
    "content": "github: neilcsmith-net\n\n"
  },
  {
    "path": ".github/workflows/maven.yml",
    "content": "name: Test on Maven\n\non:\n  [push, pull_request]\n\njobs:\n  test-1-24-jdk25:\n\n    runs-on: ubuntu-24.04\n\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v5\n\n      - name: Set up JDK 25\n        uses: actions/setup-java@v5\n        with:\n         java-version: '25'\n         distribution: 'temurin'\n\n      - name: Install GStreamer\n        run: sudo apt-get update && sudo apt-get install gstreamer1.0-plugins-good gstreamer1.0-plugins-bad\n\n      - name: Build with Maven\n        run: ./mvnw --batch-mode verify\n\n  test-1-20-jdk8:\n\n    runs-on: ubuntu-22.04\n\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v5\n\n      - name: Set up JDK 8\n        uses: actions/setup-java@v5\n        with:\n         java-version: '8'\n         distribution: 'temurin'\n\n      - name: Install GStreamer\n        run: sudo apt-get update && sudo apt-get install gstreamer1.0-plugins-good gstreamer1.0-plugins-bad\n\n      - name: Build with Maven\n        run: ./mvnw --batch-mode verify\n"
  },
  {
    "path": ".gitignore",
    "content": "*.class\n\n# Package Files #\n*.jar\n*.war\n*.ear\n/target/\n\n# Eclipse Files #\n.classpath\n.project\n.settings\n\n# NetBeans Files #\n/nbproject/\nnb-configuration.xml\n\n.idea\n"
  },
  {
    "path": ".mvn/wrapper/maven-wrapper.properties",
    "content": "wrapperVersion=3.3.4\ndistributionType=only-script\ndistributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip\ndistributionSha256Sum=0d7125e8c91097b36edb990ea5934e6c68b4440eef4ea96510a0f6815e7eeadb\n"
  },
  {
    "path": "LICENSE.md",
    "content": "\t\t   GNU LESSER GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n\n  This version of the GNU Lesser General Public License incorporates\nthe terms and conditions of version 3 of the GNU General Public\nLicense, supplemented by the additional permissions listed below.\n\n  0. Additional Definitions. \n\n  As used herein, \"this License\" refers to version 3 of the GNU Lesser\nGeneral Public License, and the \"GNU GPL\" refers to version 3 of the GNU\nGeneral Public License.\n\n  \"The Library\" refers to a covered work governed by this License,\nother than an Application or a Combined Work as defined below.\n\n  An \"Application\" is any work that makes use of an interface provided\nby the Library, but which is not otherwise based on the Library.\nDefining a subclass of a class defined by the Library is deemed a mode\nof using an interface provided by the Library.\n\n  A \"Combined Work\" is a work produced by combining or linking an\nApplication with the Library.  The particular version of the Library\nwith which the Combined Work was made is also called the \"Linked\nVersion\".\n\n  The \"Minimal Corresponding Source\" for a Combined Work means the\nCorresponding Source for the Combined Work, excluding any source code\nfor portions of the Combined Work that, considered in isolation, are\nbased on the Application, and not on the Linked Version.\n\n  The \"Corresponding Application Code\" for a Combined Work means the\nobject code and/or source code for the Application, including any data\nand utility programs needed for reproducing the Combined Work from the\nApplication, but excluding the System Libraries of the Combined Work.\n\n  1. Exception to Section 3 of the GNU GPL.\n\n  You may convey a covered work under sections 3 and 4 of this License\nwithout being bound by section 3 of the GNU GPL.\n\n  2. Conveying Modified Versions.\n\n  If you modify a copy of the Library, and, in your modifications, a\nfacility refers to a function or data to be supplied by an Application\nthat uses the facility (other than as an argument passed when the\nfacility is invoked), then you may convey a copy of the modified\nversion:\n\n   a) under this License, provided that you make a good faith effort to\n   ensure that, in the event an Application does not supply the\n   function or data, the facility still operates, and performs\n   whatever part of its purpose remains meaningful, or\n\n   b) under the GNU GPL, with none of the additional permissions of\n   this License applicable to that copy.\n\n  3. Object Code Incorporating Material from Library Header Files.\n\n  The object code form of an Application may incorporate material from\na header file that is part of the Library.  You may convey such object\ncode under terms of your choice, provided that, if the incorporated\nmaterial is not limited to numerical parameters, data structure\nlayouts and accessors, or small macros, inline functions and templates\n(ten or fewer lines in length), you do both of the following:\n\n   a) Give prominent notice with each copy of the object code that the\n   Library is used in it and that the Library and its use are\n   covered by this License.\n\n   b) Accompany the object code with a copy of the GNU GPL and this license\n   document.\n\n  4. Combined Works.\n\n  You may convey a Combined Work under terms of your choice that,\ntaken together, effectively do not restrict modification of the\nportions of the Library contained in the Combined Work and reverse\nengineering for debugging such modifications, if you also do each of\nthe following:\n\n   a) Give prominent notice with each copy of the Combined Work that\n   the Library is used in it and that the Library and its use are\n   covered by this License.\n\n   b) Accompany the Combined Work with a copy of the GNU GPL and this license\n   document.\n\n   c) For a Combined Work that displays copyright notices during\n   execution, include the copyright notice for the Library among\n   these notices, as well as a reference directing the user to the\n   copies of the GNU GPL and this license document.\n\n   d) Do one of the following:\n\n       0) Convey the Minimal Corresponding Source under the terms of this\n       License, and the Corresponding Application Code in a form\n       suitable for, and under terms that permit, the user to\n       recombine or relink the Application with a modified version of\n       the Linked Version to produce a modified Combined Work, in the\n       manner specified by section 6 of the GNU GPL for conveying\n       Corresponding Source.\n\n       1) Use a suitable shared library mechanism for linking with the\n       Library.  A suitable mechanism is one that (a) uses at run time\n       a copy of the Library already present on the user's computer\n       system, and (b) will operate properly with a modified version\n       of the Library that is interface-compatible with the Linked\n       Version. \n\n   e) Provide Installation Information, but only if you would otherwise\n   be required to provide such information under section 6 of the\n   GNU GPL, and only to the extent that such information is\n   necessary to install and execute a modified version of the\n   Combined Work produced by recombining or relinking the\n   Application with a modified version of the Linked Version. (If\n   you use option 4d0, the Installation Information must accompany\n   the Minimal Corresponding Source and Corresponding Application\n   Code. If you use option 4d1, you must provide the Installation\n   Information in the manner specified by section 6 of the GNU GPL\n   for conveying Corresponding Source.)\n\n  5. Combined Libraries.\n\n  You may place library facilities that are a work based on the\nLibrary side by side in a single library together with other library\nfacilities that are not Applications and are not covered by this\nLicense, and convey such a combined library under terms of your\nchoice, if you do both of the following:\n\n   a) Accompany the combined library with a copy of the same work based\n   on the Library, uncombined with any other library facilities,\n   conveyed under the terms of this License.\n\n   b) Give prominent notice with the combined library that part of it\n   is a work based on the Library, and explaining where to find the\n   accompanying uncombined form of the same work.\n\n  6. Revised Versions of the GNU Lesser General Public License.\n\n  The Free Software Foundation may publish revised and/or new versions\nof the GNU Lesser General Public License from time to time. Such new\nversions will be similar in spirit to the present version, but may\ndiffer in detail to address new problems or concerns.\n\n  Each version is given a distinguishing version number. If the\nLibrary as you received it specifies that a certain numbered version\nof the GNU Lesser General Public License \"or any later version\"\napplies to it, you have the option of following the terms and\nconditions either of that published version or of any later version\npublished by the Free Software Foundation. If the Library as you\nreceived it does not specify a version number of the GNU Lesser\nGeneral Public License, you may choose any version of the GNU Lesser\nGeneral Public License ever published by the Free Software Foundation.\n\n  If the Library as you received it specifies that a proxy can decide\nwhether future versions of the GNU Lesser General Public License shall\napply, that proxy's public statement of acceptance of any version is\npermanent authorization for you to choose that version for the\nLibrary.\n"
  },
  {
    "path": "README.md",
    "content": "GStreamer 1.x Java Core (gst1-java-core)\n========================================\n\ngst1-java-core is a set of Java bindings for [GStreamer 1.x][gstreamer]. GStreamer\nis an open-source, pipeline-based multimedia framework written in C. It allows a\nprogrammer to create a wide variety of media-handling pipelines inside\napplications, from simple media playback, to encoding, live-streaming, analysis,\nmachine learning, WebRTC and more.\n\nGStreamer is designed to be cross-platform, and binaries are provided for a range\nof operating systems. gst1-java-core is actively tested on Linux (x86 and Arm),\nWindows and macOS, but should work on any OS with Java, JNA and GStreamer support.\nThe bindings are in use in a wide variety of commercial and open-source projects,\nacross desktop, server and embedded.\n\n## Usage\n\nSee the [examples repository][gst1-examples] for some self-contained projects to\nget you started. Use the [Javadoc][gst1-javadoc]! - all classes are documented,\nand include links to the relevant native documentation where appropriate. Please use the\n[GStreamer-Java mailing list][gstreamer-java-group] to ask questions.\n\nTo try the examples you will need [GStreamer installed][gstreamer-download] on your\nsystem. Other options for deployment are possible - see requirements below.\n\nPlease note, this is not an easy-to-use multimedia framework for beginners. It currently\nrequires people to know the Java language and be familiar with the GStreamer framework\n(and possibly be prepared to apply things from tutorials on GStreamer programming in\nother languages to the Java bindings).\n\n## History and status\n\nReleases are available via Maven Central (under the `org.freedesktop.gstreamer`\ngroup ID), or can be downloaded from the GitHub [release page][gst1-releases].\n\nSince v1.0.0 the bindings are functionally and API stable, but note that the lowlevel\npackages are _effectively_ non-public and subject to change at any time.\n\nThe lead maintainer of the bindings is Neil C Smith at [Codelerity Ltd.][codelerity].\nThe project began in 2015 as a fork of the original [GStreamer-Java][gstreamer-java]\nbindings for GStreamer 0.10 started by Wayne Meissner. Numerous other people have made\nvaluable contributions to the original project and the 1.x fork over the years.\n\n## Help and support\n\nHelp on getting started, and support for open-source projects, can be obtained\nfrom the [GStreamer-Java mailing list][gstreamer-java-group].\n\nCommercial support and custom development is available, and sponsorship of additional\nfeatures is also welcome - please email info@codelerity.com to discuss.\n\n## Requirements\n\nThe bindings are tested on Linux, Windows and macOS. Windows and macOS installers\nfor GStreamer are available from the [GStreamer project itself][gstreamer-download].\nLinux users should be able to get GStreamer from their distribution repository if it\nisn't already installed.\n\nYou will need to have the GStreamer 1.x native libraries available in your system path\nin order to use the bindings, and may also need to set up environment variables\ndepending on how GStreamer is installed. See the `Utils` class in each example project\nfor one possible way to configure this inside your Java code.\n\nIt is possible to ship GStreamer with your application should you want your users not\nto have to install it separately. There are various ways to achieve this - see the\n[upstream documentation][gstreamer-deploy]. Advice is also available via the support\noptions above.\n\nThe minimum supported version of GStreamer is 1.8.x. If you require access to features\nrelated to later GStreamer versions (eg. WebRTC support), make sure to request the\nversion you need when calling `Gst.init(..)`\n\nYou will also need the [JNA (Java Native Access)][jna] library, minimum version 5.2.0.\n\nThe minimum required Java version is Java 8.\n\n## Contributions\n\nContributions to the library are welcomed, either to fix / enhance current features,\nor bring in new ones. There is also ongoing work to rework the lowlevel bindings.\n\n**Before opening a Pull Request** please raise an issue or discuss your contribution on\nthe mailing list. New features must have tests, selectively applied if targeting\nfeatures in versions of GStreamer above 1.8. All Pull Requests will be automatically\ntested via CI, and all tests must pass before merging will be considered.\n\nIf you are making a large contribution to benefit a commercial project, sponsorship\nof integration and support time would be appreciated.\n\n\n[gstreamer]: https://gstreamer.freedesktop.org/\n[gstreamer-download]: https://gstreamer.freedesktop.org/download/\n[gstreamer-deploy]: https://gstreamer.freedesktop.org/documentation/deploying/index.html\n[gstreamer-java]: https://github.com/gstreamer-java/gstreamer-java\n[gst1-examples]: https://github.com/gstreamer-java/gst1-java-examples\n[gst1-javadoc]: https://javadoc.io/doc/org.freedesktop.gstreamer/gst1-java-core\n[gst1-releases]: https://github.com/gstreamer-java/gst1-java-core/releases\n[gstreamer-java-group]: https://groups.google.com/forum/#!forum/gstreamer-java\n[jna]: https://github.com/java-native-access/jna\n[codelerity]: https://www.codelerity.com\n"
  },
  {
    "path": "mvnw",
    "content": "#!/bin/sh\n# ----------------------------------------------------------------------------\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n# ----------------------------------------------------------------------------\n\n# ----------------------------------------------------------------------------\n# Apache Maven Wrapper startup batch script, version 3.3.4\n#\n# Optional ENV vars\n# -----------------\n#   JAVA_HOME - location of a JDK home dir, required when download maven via java source\n#   MVNW_REPOURL - repo url base for downloading maven distribution\n#   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven\n#   MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output\n# ----------------------------------------------------------------------------\n\nset -euf\n[ \"${MVNW_VERBOSE-}\" != debug ] || set -x\n\n# OS specific support.\nnative_path() { printf %s\\\\n \"$1\"; }\ncase \"$(uname)\" in\nCYGWIN* | MINGW*)\n  [ -z \"${JAVA_HOME-}\" ] || JAVA_HOME=\"$(cygpath --unix \"$JAVA_HOME\")\"\n  native_path() { cygpath --path --windows \"$1\"; }\n  ;;\nesac\n\n# set JAVACMD and JAVACCMD\nset_java_home() {\n  # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched\n  if [ -n \"${JAVA_HOME-}\" ]; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ]; then\n      # IBM's JDK on AIX uses strange locations for the executables\n      JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n      JAVACCMD=\"$JAVA_HOME/jre/sh/javac\"\n    else\n      JAVACMD=\"$JAVA_HOME/bin/java\"\n      JAVACCMD=\"$JAVA_HOME/bin/javac\"\n\n      if [ ! -x \"$JAVACMD\" ] || [ ! -x \"$JAVACCMD\" ]; then\n        echo \"The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run.\" >&2\n        echo \"JAVA_HOME is set to \\\"$JAVA_HOME\\\", but \\\"\\$JAVA_HOME/bin/java\\\" or \\\"\\$JAVA_HOME/bin/javac\\\" does not exist.\" >&2\n        return 1\n      fi\n    fi\n  else\n    JAVACMD=\"$(\n      'set' +e\n      'unset' -f command 2>/dev/null\n      'command' -v java\n    )\" || :\n    JAVACCMD=\"$(\n      'set' +e\n      'unset' -f command 2>/dev/null\n      'command' -v javac\n    )\" || :\n\n    if [ ! -x \"${JAVACMD-}\" ] || [ ! -x \"${JAVACCMD-}\" ]; then\n      echo \"The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run.\" >&2\n      return 1\n    fi\n  fi\n}\n\n# hash string like Java String::hashCode\nhash_string() {\n  str=\"${1:-}\" h=0\n  while [ -n \"$str\" ]; do\n    char=\"${str%\"${str#?}\"}\"\n    h=$(((h * 31 + $(LC_CTYPE=C printf %d \"'$char\")) % 4294967296))\n    str=\"${str#?}\"\n  done\n  printf %x\\\\n $h\n}\n\nverbose() { :; }\n[ \"${MVNW_VERBOSE-}\" != true ] || verbose() { printf %s\\\\n \"${1-}\"; }\n\ndie() {\n  printf %s\\\\n \"$1\" >&2\n  exit 1\n}\n\ntrim() {\n  # MWRAPPER-139:\n  #   Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.\n  #   Needed for removing poorly interpreted newline sequences when running in more\n  #   exotic environments such as mingw bash on Windows.\n  printf \"%s\" \"${1}\" | tr -d '[:space:]'\n}\n\nscriptDir=\"$(dirname \"$0\")\"\nscriptName=\"$(basename \"$0\")\"\n\n# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties\nwhile IFS=\"=\" read -r key value; do\n  case \"${key-}\" in\n  distributionUrl) distributionUrl=$(trim \"${value-}\") ;;\n  distributionSha256Sum) distributionSha256Sum=$(trim \"${value-}\") ;;\n  esac\ndone <\"$scriptDir/.mvn/wrapper/maven-wrapper.properties\"\n[ -n \"${distributionUrl-}\" ] || die \"cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties\"\n\ncase \"${distributionUrl##*/}\" in\nmaven-mvnd-*bin.*)\n  MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/\n  case \"${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)\" in\n  *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;\n  :Darwin*x86_64) distributionPlatform=darwin-amd64 ;;\n  :Darwin*arm64) distributionPlatform=darwin-aarch64 ;;\n  :Linux*x86_64*) distributionPlatform=linux-amd64 ;;\n  *)\n    echo \"Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version\" >&2\n    distributionPlatform=linux-amd64\n    ;;\n  esac\n  distributionUrl=\"${distributionUrl%-bin.*}-$distributionPlatform.zip\"\n  ;;\nmaven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;\n*) MVN_CMD=\"mvn${scriptName#mvnw}\" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;\nesac\n\n# apply MVNW_REPOURL and calculate MAVEN_HOME\n# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>\n[ -z \"${MVNW_REPOURL-}\" ] || distributionUrl=\"$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*\"$_MVNW_REPO_PATTERN\"}\"\ndistributionUrlName=\"${distributionUrl##*/}\"\ndistributionUrlNameMain=\"${distributionUrlName%.*}\"\ndistributionUrlNameMain=\"${distributionUrlNameMain%-bin}\"\nMAVEN_USER_HOME=\"${MAVEN_USER_HOME:-${HOME}/.m2}\"\nMAVEN_HOME=\"${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string \"$distributionUrl\")\"\n\nexec_maven() {\n  unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :\n  exec \"$MAVEN_HOME/bin/$MVN_CMD\" \"$@\" || die \"cannot exec $MAVEN_HOME/bin/$MVN_CMD\"\n}\n\nif [ -d \"$MAVEN_HOME\" ]; then\n  verbose \"found existing MAVEN_HOME at $MAVEN_HOME\"\n  exec_maven \"$@\"\nfi\n\ncase \"${distributionUrl-}\" in\n*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;\n*) die \"distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'\" ;;\nesac\n\n# prepare tmp dir\nif TMP_DOWNLOAD_DIR=\"$(mktemp -d)\" && [ -d \"$TMP_DOWNLOAD_DIR\" ]; then\n  clean() { rm -rf -- \"$TMP_DOWNLOAD_DIR\"; }\n  trap clean HUP INT TERM EXIT\nelse\n  die \"cannot create temp dir\"\nfi\n\nmkdir -p -- \"${MAVEN_HOME%/*}\"\n\n# Download and Install Apache Maven\nverbose \"Couldn't find MAVEN_HOME, downloading and installing it ...\"\nverbose \"Downloading from: $distributionUrl\"\nverbose \"Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName\"\n\n# select .zip or .tar.gz\nif ! command -v unzip >/dev/null; then\n  distributionUrl=\"${distributionUrl%.zip}.tar.gz\"\n  distributionUrlName=\"${distributionUrl##*/}\"\nfi\n\n# verbose opt\n__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''\n[ \"${MVNW_VERBOSE-}\" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v\n\n# normalize http auth\ncase \"${MVNW_PASSWORD:+has-password}\" in\n'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;\nhas-password) [ -n \"${MVNW_USERNAME-}\" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;\nesac\n\nif [ -z \"${MVNW_USERNAME-}\" ] && command -v wget >/dev/null; then\n  verbose \"Found wget ... using wget\"\n  wget ${__MVNW_QUIET_WGET:+\"$__MVNW_QUIET_WGET\"} \"$distributionUrl\" -O \"$TMP_DOWNLOAD_DIR/$distributionUrlName\" || die \"wget: Failed to fetch $distributionUrl\"\nelif [ -z \"${MVNW_USERNAME-}\" ] && command -v curl >/dev/null; then\n  verbose \"Found curl ... using curl\"\n  curl ${__MVNW_QUIET_CURL:+\"$__MVNW_QUIET_CURL\"} -f -L -o \"$TMP_DOWNLOAD_DIR/$distributionUrlName\" \"$distributionUrl\" || die \"curl: Failed to fetch $distributionUrl\"\nelif set_java_home; then\n  verbose \"Falling back to use Java to download\"\n  javaSource=\"$TMP_DOWNLOAD_DIR/Downloader.java\"\n  targetZip=\"$TMP_DOWNLOAD_DIR/$distributionUrlName\"\n  cat >\"$javaSource\" <<-END\n\tpublic class Downloader extends java.net.Authenticator\n\t{\n\t  protected java.net.PasswordAuthentication getPasswordAuthentication()\n\t  {\n\t    return new java.net.PasswordAuthentication( System.getenv( \"MVNW_USERNAME\" ), System.getenv( \"MVNW_PASSWORD\" ).toCharArray() );\n\t  }\n\t  public static void main( String[] args ) throws Exception\n\t  {\n\t    setDefault( new Downloader() );\n\t    java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );\n\t  }\n\t}\n\tEND\n  # For Cygwin/MinGW, switch paths to Windows format before running javac and java\n  verbose \" - Compiling Downloader.java ...\"\n  \"$(native_path \"$JAVACCMD\")\" \"$(native_path \"$javaSource\")\" || die \"Failed to compile Downloader.java\"\n  verbose \" - Running Downloader.java ...\"\n  \"$(native_path \"$JAVACMD\")\" -cp \"$(native_path \"$TMP_DOWNLOAD_DIR\")\" Downloader \"$distributionUrl\" \"$(native_path \"$targetZip\")\"\nfi\n\n# If specified, validate the SHA-256 sum of the Maven distribution zip file\nif [ -n \"${distributionSha256Sum-}\" ]; then\n  distributionSha256Result=false\n  if [ \"$MVN_CMD\" = mvnd.sh ]; then\n    echo \"Checksum validation is not supported for maven-mvnd.\" >&2\n    echo \"Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties.\" >&2\n    exit 1\n  elif command -v sha256sum >/dev/null; then\n    if echo \"$distributionSha256Sum  $TMP_DOWNLOAD_DIR/$distributionUrlName\" | sha256sum -c - >/dev/null 2>&1; then\n      distributionSha256Result=true\n    fi\n  elif command -v shasum >/dev/null; then\n    if echo \"$distributionSha256Sum  $TMP_DOWNLOAD_DIR/$distributionUrlName\" | shasum -a 256 -c >/dev/null 2>&1; then\n      distributionSha256Result=true\n    fi\n  else\n    echo \"Checksum validation was requested but neither 'sha256sum' or 'shasum' are available.\" >&2\n    echo \"Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties.\" >&2\n    exit 1\n  fi\n  if [ $distributionSha256Result = false ]; then\n    echo \"Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised.\" >&2\n    echo \"If you updated your Maven version, you need to update the specified distributionSha256Sum property.\" >&2\n    exit 1\n  fi\nfi\n\n# unzip and move\nif command -v unzip >/dev/null; then\n  unzip ${__MVNW_QUIET_UNZIP:+\"$__MVNW_QUIET_UNZIP\"} \"$TMP_DOWNLOAD_DIR/$distributionUrlName\" -d \"$TMP_DOWNLOAD_DIR\" || die \"failed to unzip\"\nelse\n  tar xzf${__MVNW_QUIET_TAR:+\"$__MVNW_QUIET_TAR\"} \"$TMP_DOWNLOAD_DIR/$distributionUrlName\" -C \"$TMP_DOWNLOAD_DIR\" || die \"failed to untar\"\nfi\n\n# Find the actual extracted directory name (handles snapshots where filename != directory name)\nactualDistributionDir=\"\"\n\n# First try the expected directory name (for regular distributions)\nif [ -d \"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain\" ]; then\n  if [ -f \"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD\" ]; then\n    actualDistributionDir=\"$distributionUrlNameMain\"\n  fi\nfi\n\n# If not found, search for any directory with the Maven executable (for snapshots)\nif [ -z \"$actualDistributionDir\" ]; then\n  # enable globbing to iterate over items\n  set +f\n  for dir in \"$TMP_DOWNLOAD_DIR\"/*; do\n    if [ -d \"$dir\" ]; then\n      if [ -f \"$dir/bin/$MVN_CMD\" ]; then\n        actualDistributionDir=\"$(basename \"$dir\")\"\n        break\n      fi\n    fi\n  done\n  set -f\nfi\n\nif [ -z \"$actualDistributionDir\" ]; then\n  verbose \"Contents of $TMP_DOWNLOAD_DIR:\"\n  verbose \"$(ls -la \"$TMP_DOWNLOAD_DIR\")\"\n  die \"Could not find Maven distribution directory in extracted archive\"\nfi\n\nverbose \"Found extracted Maven distribution directory: $actualDistributionDir\"\nprintf %s\\\\n \"$distributionUrl\" >\"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url\"\nmv -- \"$TMP_DOWNLOAD_DIR/$actualDistributionDir\" \"$MAVEN_HOME\" || [ -d \"$MAVEN_HOME\" ] || die \"fail to move MAVEN_HOME\"\n\nclean || :\nexec_maven \"$@\"\n"
  },
  {
    "path": "mvnw.cmd",
    "content": "<# : batch portion\r\n@REM ----------------------------------------------------------------------------\r\n@REM Licensed to the Apache Software Foundation (ASF) under one\r\n@REM or more contributor license agreements.  See the NOTICE file\r\n@REM distributed with this work for additional information\r\n@REM regarding copyright ownership.  The ASF licenses this file\r\n@REM to you under the Apache License, Version 2.0 (the\r\n@REM \"License\"); you may not use this file except in compliance\r\n@REM with the License.  You may obtain a copy of the License at\r\n@REM\r\n@REM    http://www.apache.org/licenses/LICENSE-2.0\r\n@REM\r\n@REM Unless required by applicable law or agreed to in writing,\r\n@REM software distributed under the License is distributed on an\r\n@REM \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r\n@REM KIND, either express or implied.  See the License for the\r\n@REM specific language governing permissions and limitations\r\n@REM under the License.\r\n@REM ----------------------------------------------------------------------------\r\n\r\n@REM ----------------------------------------------------------------------------\r\n@REM Apache Maven Wrapper startup batch script, version 3.3.4\r\n@REM\r\n@REM Optional ENV vars\r\n@REM   MVNW_REPOURL - repo url base for downloading maven distribution\r\n@REM   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven\r\n@REM   MVNW_VERBOSE - true: enable verbose log; others: silence the output\r\n@REM ----------------------------------------------------------------------------\r\n\r\n@IF \"%__MVNW_ARG0_NAME__%\"==\"\" (SET __MVNW_ARG0_NAME__=%~nx0)\r\n@SET __MVNW_CMD__=\r\n@SET __MVNW_ERROR__=\r\n@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%\r\n@SET PSModulePath=\r\n@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 @(\r\n  IF \"%%A\"==\"MVN_CMD\" (set __MVNW_CMD__=%%B) ELSE IF \"%%B\"==\"\" (echo %%A) ELSE (echo %%A=%%B)\r\n)\r\n@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%\r\n@SET __MVNW_PSMODULEP_SAVE=\r\n@SET __MVNW_ARG0_NAME__=\r\n@SET MVNW_USERNAME=\r\n@SET MVNW_PASSWORD=\r\n@IF NOT \"%__MVNW_CMD__%\"==\"\" (\"%__MVNW_CMD__%\" %*)\r\n@echo Cannot start maven from wrapper >&2 && exit /b 1\r\n@GOTO :EOF\r\n: end batch / begin powershell #>\r\n\r\n$ErrorActionPreference = \"Stop\"\r\nif ($env:MVNW_VERBOSE -eq \"true\") {\r\n  $VerbosePreference = \"Continue\"\r\n}\r\n\r\n# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties\r\n$distributionUrl = (Get-Content -Raw \"$scriptDir/.mvn/wrapper/maven-wrapper.properties\" | ConvertFrom-StringData).distributionUrl\r\nif (!$distributionUrl) {\r\n  Write-Error \"cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties\"\r\n}\r\n\r\nswitch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {\r\n  \"maven-mvnd-*\" {\r\n    $USE_MVND = $true\r\n    $distributionUrl = $distributionUrl -replace '-bin\\.[^.]*$',\"-windows-amd64.zip\"\r\n    $MVN_CMD = \"mvnd.cmd\"\r\n    break\r\n  }\r\n  default {\r\n    $USE_MVND = $false\r\n    $MVN_CMD = $script -replace '^mvnw','mvn'\r\n    break\r\n  }\r\n}\r\n\r\n# apply MVNW_REPOURL and calculate MAVEN_HOME\r\n# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>\r\nif ($env:MVNW_REPOURL) {\r\n  $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { \"/org/apache/maven/\" } else { \"/maven/mvnd/\" }\r\n  $distributionUrl = \"$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace \"^.*$MVNW_REPO_PATTERN\",'')\"\r\n}\r\n$distributionUrlName = $distributionUrl -replace '^.*/',''\r\n$distributionUrlNameMain = $distributionUrlName -replace '\\.[^.]*$','' -replace '-bin$',''\r\n\r\n$MAVEN_M2_PATH = \"$HOME/.m2\"\r\nif ($env:MAVEN_USER_HOME) {\r\n  $MAVEN_M2_PATH = \"$env:MAVEN_USER_HOME\"\r\n}\r\n\r\nif (-not (Test-Path -Path $MAVEN_M2_PATH)) {\r\n    New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null\r\n}\r\n\r\n$MAVEN_WRAPPER_DISTS = $null\r\nif ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) {\r\n  $MAVEN_WRAPPER_DISTS = \"$MAVEN_M2_PATH/wrapper/dists\"\r\n} else {\r\n  $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + \"/wrapper/dists\"\r\n}\r\n\r\n$MAVEN_HOME_PARENT = \"$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain\"\r\n$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString(\"x2\")}) -join ''\r\n$MAVEN_HOME = \"$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME\"\r\n\r\nif (Test-Path -Path \"$MAVEN_HOME\" -PathType Container) {\r\n  Write-Verbose \"found existing MAVEN_HOME at $MAVEN_HOME\"\r\n  Write-Output \"MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD\"\r\n  exit $?\r\n}\r\n\r\nif (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {\r\n  Write-Error \"distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl\"\r\n}\r\n\r\n# prepare tmp dir\r\n$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile\r\n$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path \"$TMP_DOWNLOAD_DIR_HOLDER.dir\"\r\n$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null\r\ntrap {\r\n  if ($TMP_DOWNLOAD_DIR.Exists) {\r\n    try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }\r\n    catch { Write-Warning \"Cannot remove $TMP_DOWNLOAD_DIR\" }\r\n  }\r\n}\r\n\r\nNew-Item -Itemtype Directory -Path \"$MAVEN_HOME_PARENT\" -Force | Out-Null\r\n\r\n# Download and Install Apache Maven\r\nWrite-Verbose \"Couldn't find MAVEN_HOME, downloading and installing it ...\"\r\nWrite-Verbose \"Downloading from: $distributionUrl\"\r\nWrite-Verbose \"Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName\"\r\n\r\n$webclient = New-Object System.Net.WebClient\r\nif ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {\r\n  $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)\r\n}\r\n[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\r\n$webclient.DownloadFile($distributionUrl, \"$TMP_DOWNLOAD_DIR/$distributionUrlName\") | Out-Null\r\n\r\n# If specified, validate the SHA-256 sum of the Maven distribution zip file\r\n$distributionSha256Sum = (Get-Content -Raw \"$scriptDir/.mvn/wrapper/maven-wrapper.properties\" | ConvertFrom-StringData).distributionSha256Sum\r\nif ($distributionSha256Sum) {\r\n  if ($USE_MVND) {\r\n    Write-Error \"Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties.\"\r\n  }\r\n  Import-Module $PSHOME\\Modules\\Microsoft.PowerShell.Utility -Function Get-FileHash\r\n  if ((Get-FileHash \"$TMP_DOWNLOAD_DIR/$distributionUrlName\" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {\r\n    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.\"\r\n  }\r\n}\r\n\r\n# unzip and move\r\nExpand-Archive \"$TMP_DOWNLOAD_DIR/$distributionUrlName\" -DestinationPath \"$TMP_DOWNLOAD_DIR\" | Out-Null\r\n\r\n# Find the actual extracted directory name (handles snapshots where filename != directory name)\r\n$actualDistributionDir = \"\"\r\n\r\n# First try the expected directory name (for regular distributions)\r\n$expectedPath = Join-Path \"$TMP_DOWNLOAD_DIR\" \"$distributionUrlNameMain\"\r\n$expectedMvnPath = Join-Path \"$expectedPath\" \"bin/$MVN_CMD\"\r\nif ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) {\r\n  $actualDistributionDir = $distributionUrlNameMain\r\n}\r\n\r\n# If not found, search for any directory with the Maven executable (for snapshots)\r\nif (!$actualDistributionDir) {\r\n  Get-ChildItem -Path \"$TMP_DOWNLOAD_DIR\" -Directory | ForEach-Object {\r\n    $testPath = Join-Path $_.FullName \"bin/$MVN_CMD\"\r\n    if (Test-Path -Path $testPath -PathType Leaf) {\r\n      $actualDistributionDir = $_.Name\r\n    }\r\n  }\r\n}\r\n\r\nif (!$actualDistributionDir) {\r\n  Write-Error \"Could not find Maven distribution directory in extracted archive\"\r\n}\r\n\r\nWrite-Verbose \"Found extracted Maven distribution directory: $actualDistributionDir\"\r\nRename-Item -Path \"$TMP_DOWNLOAD_DIR/$actualDistributionDir\" -NewName $MAVEN_HOME_NAME | Out-Null\r\ntry {\r\n  Move-Item -Path \"$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME\" -Destination $MAVEN_HOME_PARENT | Out-Null\r\n} catch {\r\n  if (! (Test-Path -Path \"$MAVEN_HOME\" -PathType Container)) {\r\n    Write-Error \"fail to move MAVEN_HOME\"\r\n  }\r\n} finally {\r\n  try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }\r\n  catch { Write-Warning \"Cannot remove $TMP_DOWNLOAD_DIR\" }\r\n}\r\n\r\nWrite-Output \"MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD\"\r\n"
  },
  {
    "path": "nbactions.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<actions>\n        <action>\n            <actionName>run</actionName>\n            <packagings>\n                <packaging>jar</packaging>\n            </packagings>\n            <goals>\n                <goal>process-classes</goal>\n                <goal>org.codehaus.mojo:exec-maven-plugin:1.2.1:exec</goal>\n            </goals>\n            <properties>\n                <exec.args>-Djna.nosys=true -classpath %classpath ${packageClassName}</exec.args>\n                <exec.executable>java</exec.executable>\n            </properties>\n        </action>\n        <action>\n            <actionName>debug</actionName>\n            <packagings>\n                <packaging>jar</packaging>\n            </packagings>\n            <goals>\n                <goal>process-classes</goal>\n                <goal>org.codehaus.mojo:exec-maven-plugin:1.2.1:exec</goal>\n            </goals>\n            <properties>\n                <exec.args>-Xdebug -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} -Djna.nosys=true -classpath %classpath ${packageClassName}</exec.args>\n                <exec.executable>java</exec.executable>\n                <jpda.listen>true</jpda.listen>\n            </properties>\n        </action>\n        <action>\n            <actionName>profile</actionName>\n            <packagings>\n                <packaging>jar</packaging>\n            </packagings>\n            <goals>\n                <goal>process-classes</goal>\n                <goal>org.codehaus.mojo:exec-maven-plugin:1.2.1:exec</goal>\n            </goals>\n            <properties>\n                <exec.args>-Djna.nosys=true -classpath %classpath ${packageClassName}</exec.args>\n                <exec.executable>java</exec.executable>\n            </properties>\n        </action>\n        <action>\n            <actionName>run.single.main</actionName>\n            <packagings>\n                <packaging>*</packaging>\n            </packagings>\n            <goals>\n                <goal>process-classes</goal>\n                <goal>org.codehaus.mojo:exec-maven-plugin:1.2.1:exec</goal>\n            </goals>\n            <properties>\n                <exec.args>-Djna.nosys=true -classpath %classpath ${packageClassName}</exec.args>\n                <exec.executable>java</exec.executable>\n                <exec.classpathScope>${classPathScope}</exec.classpathScope>\n            </properties>\n        </action>\n        <action>\n            <actionName>test</actionName>\n            <packagings>\n                <packaging>*</packaging>\n            </packagings>\n            <goals>\n                <goal>test</goal>\n            </goals>\n            <properties>\n                <exec.args>-Djna.nosys=true</exec.args>\n            </properties>\n        </action>\n        <action>\n            <actionName>test.single</actionName>\n            <packagings>\n                <packaging>*</packaging>\n            </packagings>\n            <goals>\n                <goal>test-compile</goal>\n                <goal>surefire:test</goal>\n            </goals>\n            <properties>\n                <exec.args>-Djna.nosys=true</exec.args>\n                <test>${packageClassName}</test>\n            </properties>\n        </action>\n    </actions>\n"
  },
  {
    "path": "pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n\n  <modelVersion>4.0.0</modelVersion>\n\n  <groupId>org.freedesktop.gstreamer</groupId>\n  <artifactId>gst1-java-core</artifactId>\n  <version>1.5.0-SNAPSHOT</version>\n  <packaging>jar</packaging>\n\n  <name>GStreamer 1.x Java Core</name>\n  <description>Unofficial Java binding for the GStreamer framework</description>\n  <url>https://github.com/gstreamer-java/gst1-java-core</url>\n\n  <organization>\n    <name>gstreamer-java</name>\n    <url>http://www.github.com/gstreamer-java</url>\n  </organization>\n\n  <licenses>\n    <license>\n      <name>LGPL-3.0-only</name>\n      <url>http://www.gnu.org/licenses/lgpl.html</url>\n      <distribution>repo</distribution>\n    </license>\n  </licenses>\n\n  <scm>\n    <url>https://github.com/gstreamer-java/gst1-java-core</url>\n    <connection>scm:git:https://github.com/gstreamer-java/gst1-java-core.git</connection>\n    <developerConnection>scm:git:https://github.com/gstreamer-java/gst1-java-core.git</developerConnection>\n  </scm>\n  \n  <distributionManagement>\n    <snapshotRepository>\n      <id>sonatype-central</id>\n      <url>https://central.sonatype.com/repository/maven-snapshots</url>\n    </snapshotRepository>\n    <repository>\n      <id>sonatype-central</id>\n      <url>https://repo.maven.apache.org/maven2</url>\n    </repository>\n  </distributionManagement>\n\n  <developers>\n    <developer>\n      <id>neilcsmith-net</id>\n      <name>Neil C Smith</name>\n      <organization>Codelerity Ltd.</organization>\n      <email>neil@codelerity.com</email>\n      <roles>\n        <role>Lead maintainer</role>\n        <role>Developer</role>\n      </roles>\n      <url>https://www.codelerity.com</url>\n    </developer>\n    <developer>\n      <id>wmeissner</id>\n      <name>Wayne Meissner</name>\n      <roles>\n        <role>Founder of GStreamer 0.10 bindings</role>\n      </roles>\n    </developer>\n  </developers>\n\n  <properties>\n    <maven.compiler.release>8</maven.compiler.release>\n    <maven.test.jvmargs></maven.test.jvmargs>\n    <njord.version>0.8.5</njord.version>\n    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n  </properties>\n\n  <dependencies>\n    <dependency>\n      <groupId>junit</groupId>\n      <artifactId>junit</artifactId>\n      <version>4.13.2</version>\n      <scope>test</scope>\n    </dependency>\n    <dependency>\n      <groupId>net.java.dev.jna</groupId>\n      <artifactId>jna</artifactId>\n      <version>5.18.1</version>\n    </dependency>\n  </dependencies>\n\n  <build>\n    <sourceDirectory>src</sourceDirectory>\n    <resources>\n      <resource>\n        <directory>src</directory>\n        <excludes>\n          <exclude>**/*.java</exclude>\n        </excludes>\n      </resource>\n    </resources>\n    <testSourceDirectory>test</testSourceDirectory>\n    <testResources>\n      <testResource>\n        <directory>test</directory>\n        <excludes>\n          <exclude>**/*.java</exclude>\n        </excludes>\n      </testResource>\n    </testResources>\n    <extensions>\n      <extension>\n        <groupId>eu.maveniverse.maven.njord</groupId>\n        <artifactId>extension3</artifactId>\n        <version>${njord.version}</version>\n      </extension>\n    </extensions>\n    <plugins>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-surefire-plugin</artifactId>\n        <version>3.5.4</version>\n        <configuration>\n          <forkCount>1</forkCount>\n          <parallel>none</parallel>\n          <reuseForks>false</reuseForks>\n          <argLine>-XX:+IgnoreUnrecognizedVMOptions --enable-native-access=ALL-UNNAMED -Djna.nosys=true ${maven.test.jvmargs}</argLine>\n          <excludes>\n            <exclude>**/Test*.java</exclude>\n          </excludes>\n        </configuration>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-compiler-plugin</artifactId>\n        <version>3.14.1</version>\n        <configuration>\n          <release>8</release>\n        </configuration>\n      </plugin>\n      <plugin>\n        <groupId>org.apache.maven.plugins</groupId>\n        <artifactId>maven-jar-plugin</artifactId>\n        <version>3.4.2</version>\n        <configuration>\n          <archive>\n            <manifestEntries>\n              <Automatic-Module-Name>org.freedesktop.gstreamer</Automatic-Module-Name>\n            </manifestEntries>\n          </archive>\n        </configuration>\n      </plugin>\n    </plugins>\n  </build>\n\n  <profiles>\n    <profile>\n      <id>windows-gstreamer-path</id>\n      <activation>\n        <os>\n          <family>windows</family>\n        </os>\n        <property>\n          <name>gstreamer.path</name>\n        </property>\n      </activation>\n      <build>\n        <plugins>\n          <plugin>\n            <groupId>org.apache.maven.plugins</groupId>\n            <artifactId>maven-surefire-plugin</artifactId>\n            <configuration>\n              <environmentVariables>\n                <PATH>${gstreamer.path};${java.library.path}</PATH>\n              </environmentVariables>\n            </configuration>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n    <profile>\n      <id>release</id>\n      <build>\n        <plugins>\n          <plugin>\n            <groupId>org.apache.maven.plugins</groupId>\n            <artifactId>maven-source-plugin</artifactId>\n            <version>3.3.1</version>\n            <executions>\n              <execution>\n                <id>attach-sources</id>\n                <goals>\n                  <goal>jar-no-fork</goal>\n                </goals>\n              </execution>\n            </executions>\n          </plugin>\n          <plugin>\n            <groupId>org.apache.maven.plugins</groupId>\n            <artifactId>maven-javadoc-plugin</artifactId>\n            <version>3.12.0</version>\n            <configuration>\n              <doclint>none</doclint>\n              <excludePackageNames>org.freedesktop.gstreamer.lowlevel</excludePackageNames>\n              <release>8</release>\n            </configuration>\n            <executions>\n              <execution>\n                <id>attach-javadocs</id>\n                <goals>\n                  <goal>jar</goal>\n                </goals>\n              </execution>\n            </executions>\n          </plugin>\n          <plugin>\n            <groupId>org.apache.maven.plugins</groupId>\n            <artifactId>maven-gpg-plugin</artifactId>\n            <version>3.2.8</version>\n            <executions>\n              <execution>\n                <id>sign-artifacts</id>\n                <phase>verify</phase>\n                <goals>\n                  <goal>sign</goal>\n                </goals>\n              </execution>\n            </executions>\n          </plugin>\n        </plugins>\n      </build>\n    </profile>\n  </profiles>\n</project>\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/Bin.java",
    "content": "/* \n * Copyright (c) 2025 Neil C Smith\n * Copyright (c) 2016 Christophe Lafolet\n * Copyright (c) 2009 Levente Farkas\n * Copyright (C) 2007 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2004 Wim Taymans <wim@fluendo.com>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstBinAPI.GSTBIN_API;\n\nimport java.util.EnumSet;\nimport java.util.List;\nimport org.freedesktop.gstreamer.glib.NativeFlags;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback;\nimport org.freedesktop.gstreamer.lowlevel.GstIteratorPtr;\nimport org.freedesktop.gstreamer.lowlevel.GstObjectPtr;\n\n/**\n * Base class and element that can contain other elements.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstBin.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstBin.html</a>\n * <p>\n * Bin is an element that can contain other {@link Element}s, allowing them to\n * be managed as a group.\n * <p>\n * Pads from the child elements can be ghosted to the bin, see {@link GhostPad}.\n * This makes the bin look like any other elements and enables creation of\n * higher-level abstraction elements.\n * <p>\n * A new {@link Bin} is created with {@link Bin#Bin(String)}. Use a\n * {@link Pipeline} instead if you want to create a toplevel bin because a\n * normal bin doesn't have a bus or handle clock distribution of its own.\n * <p>\n * After the bin has been created you will typically add elements to it with\n * {@link Bin#add(Element)}. Elements can be removed with\n * {@link Bin#remove(Element)}\n * <p>\n * An element can be retrieved from a bin with\n * {@link Bin#getElementByName(String)}.\n * <p>\n * A list of elements contained in a bin can be retrieved with\n * {@link Bin#getElements}\n *\n * The {@link ELEMENT_ADDED} signal is fired whenever a new element is added to\n * the bin. Likewise the {@link ELEMENT_REMOVED} signal is fired whenever an\n * element is removed from the bin.\n *\n */\npublic class Bin extends Element {\n\n    public static final String GST_NAME = \"bin\";\n    public static final String GTYPE_NAME = \"GstBin\";\n\n    protected Bin(Initializer init) {\n        super(init);\n    }\n\n    Bin(Handle handle, boolean needRef) {\n        super(handle, needRef);\n    }\n    \n    /**\n     * Creates a new Bin with a unique name.\n     */\n    public Bin() {\n        this(Natives.initializer(GSTBIN_API.ptr_gst_bin_new(null), false, true));\n    }\n\n    /**\n     * Creates a new Bin with the given name.\n     *\n     * @param name The Name to assign to the new Bin\n     */\n    public Bin(String name) {\n        this(Natives.initializer(GSTBIN_API.ptr_gst_bin_new(name), false, true));\n    }\n\n    /**\n     * Adds an Element to this Bin.\n     * <p>\n     * Sets the element's parent, and thus takes ownership of the element. An\n     * element can only be added to one bin.\n     * <p>\n     * If the element's pads are linked to other pads, the pads will be unlinked\n     * before the element is added to the bin.\n     *\n     * @param element The {@link Element} to add to this Bin.\n     * @return true if the element was successfully added, false if the Bin will\n     * not accept the element.\n     */\n    public boolean add(Element element) {\n        return GSTBIN_API.gst_bin_add(this, element);\n    }\n\n    /**\n     * Adds an array of Element objects to this Bin\n     *\n     * @param elements The array of {@link Element} to add to this Bin\n     * @see Bin#add(Element)\n     */\n    public void addMany(Element... elements) {\n        GSTBIN_API.gst_bin_add_many(this, elements);\n    }\n\n    /**\n     * Removes a Element from this Bin\n     * <p>\n     * Removes the element from the bin, unparenting it as well.\n     *\n     * If the element's pads are linked to other pads, the pads will be unlinked\n     * before the element is removed from the bin.\n     *\n     * @param element The {@link Element} to remove\n     * @return true if the element was successfully removed\n     */\n    public boolean remove(Element element) {\n        return GSTBIN_API.gst_bin_remove(this, element);\n    }\n\n    /**\n     * Removes an array of {@link Element} objects from this Bin\n     *\n     * @param elements The list {@link Element} to remove\n     */\n    public void removeMany(Element... elements) {\n        GSTBIN_API.gst_bin_remove_many(this, elements);\n    }\n\n    private List<Element> elementList(GstIteratorPtr iter) {\n        return GstIterator.asList(iter, Element.class);\n    }\n\n    /**\n     * Retrieve a list of the {@link Element}s contained in the Bin.\n     *\n     * @return The List of {@link Element}s.\n     */\n    public List<Element> getElements() {\n        return elementList(GSTBIN_API.gst_bin_iterate_elements(this));\n    }\n\n    /**\n     * Gets an a list of the elements in this bin in topologically sorted order.\n     * This means that the elements are returned from the most downstream\n     * elements (sinks) to the sources.\n     *\n     * @return The List of {@link Element}s.\n     */\n    public List<Element> getElementsSorted() {\n        return elementList(GSTBIN_API.gst_bin_iterate_sorted(this));\n    }\n\n    /**\n     * Retrieve a list of the {@link Element}s contained in the Bin and its Bin\n     * children.\n     *\n     * This differs from {@link #getElements()} as it will also return\n     * {@link Element}s that are in any Bin elements contained in this Bin, also\n     * recursing down those Bins.\n     *\n     * @return The List of {@link Element}s.\n     */\n    public List<Element> getElementsRecursive() {\n        return elementList(GSTBIN_API.gst_bin_iterate_recurse(this));\n    }\n\n    /**\n     * Retrieve a list of the sink {@link Element}s contained in the Bin.\n     *\n     * @return The List of sink {@link Element}s.\n     */\n    public List<Element> getSinks() {\n        return elementList(GSTBIN_API.gst_bin_iterate_sinks(this));\n    }\n\n    /**\n     * Retrieve a list of the source {@link Element}s contained in the Bin.\n     *\n     * @return The List of source {@link Element}s.\n     */\n    public List<Element> getSources() {\n        return elementList(GSTBIN_API.gst_bin_iterate_sources(this));\n    }\n\n    /**\n     * Gets the {@link Element} with the given name from the bin. This function\n     * recurses into child bins.\n     *\n     * @param name The name of the {@link Element} to find.\n     * @return The {@link Element} if found, else null.\n     */\n    public Element getElementByName(String name) {\n        return GSTBIN_API.gst_bin_get_by_name(this, name);\n    }\n\n    /**\n     * Gets the element with the given name from this bin. If the element is not\n     * found, a recursion is performed on the parent bin.\n     *\n     * @param name The name of the {@link Element} to find.\n     * @return The {@link Element} if found, else null.\n     */\n    public Element getElementByNameRecurseUp(String name) {\n        return GSTBIN_API.gst_bin_get_by_name_recurse_up(this, name);\n    }\n\n//    /**\n//     * Looks for an element inside the bin that implements the given interface.\n//     * If such an element is found, it returns the element.\n//     *\n//     * @param iface The class of the {@link Element} to search for.\n//     * @return The {@link Element} that implements the interface.\n//     */\n//    public <T extends Element> T getElementByInterface(Class<T> iface) {\n//        return iface.cast(GSTBIN_API.gst_bin_get_by_interface(this, GstTypes.typeFor(iface)));\n//    }\n    /**\n     * To aid debugging applications one can use this method to write out the\n     * whole network of gstreamer elements that form the pipeline into a dot\n     * file. This file can be processed with graphviz to get an image. e.g. dot\n     * -Tpng -oimage.png graph_lowlevel.dot\n     * <p>\n     * The function is only active if gstreamer is configured with\n     * \"--gst-enable-gst-debug\" and the environment variable\n     * GST_DEBUG_DUMP_DOT_DIR is set to a basepath (e.g. /tmp).\n     *\n     * @param details to show in the graph\n     * @param fileName output base filename (e.g. \"myplayer\")\n     */\n    public void debugToDotFile(EnumSet<DebugGraphDetails> details, String fileName) {\n        GSTBIN_API.gst_debug_bin_to_dot_file(\n                this, NativeFlags.toInt(details), fileName);\n    }\n\n    /**\n     * To aid debugging applications one can use this method to write out the\n     * whole network of gstreamer elements that form the pipeline into a dot\n     * file. This file can be processed with graphviz to get an image. e.g. dot\n     * -Tpng -oimage.png graph_lowlevel.dot\n     * <p>\n     * The function is only active if gstreamer is configured with\n     * \"--gst-enable-gst-debug\" and the environment variable\n     * GST_DEBUG_DUMP_DOT_DIR is set to a basepath (e.g. /tmp).\n     * <p>\n     * Unlike {@link #debugToDotFile(java.util.EnumSet, java.lang.String)} this\n     * method adds the current timestamp to the filename, so that it can be\n     * used to take multiple snapshots.\n     * \n     * @param details to show in the graph\n     * @param fileName output base filename (e.g. \"myplayer\")\n     */\n    public void debugToDotFileWithTS(EnumSet<DebugGraphDetails> details, String fileName) {\n        GSTBIN_API.gst_debug_bin_to_dot_file_with_ts(\n                this, NativeFlags.toInt(details), fileName);\n    }\n\n    /**\n     * Signal emitted when an {@link Element} is added to this Bin\n     *\n     * @see #connect(ELEMENT_ADDED)\n     * @see #disconnect(ELEMENT_ADDED)\n     */\n    public static interface ELEMENT_ADDED {\n\n        /**\n         * Called when an {@link Element} is added to a {@link Bin}\n         *\n         * @param bin the Bin the element was added to.\n         * @param element the {@link Element} that was added.\n         */\n        public void elementAdded(Bin bin, Element element);\n    }\n\n    /**\n     * Add a listener for the <code>element-added</code> signal on this Bin\n     *\n     * @param listener The listener to be called when an {@link Element} is\n     * added.\n     */\n    public void connect(final ELEMENT_ADDED listener) {\n        connect(ELEMENT_ADDED.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(Bin bin, Element elem) {\n                listener.elementAdded(bin, elem);\n            }\n        });\n    }\n\n    /**\n     * Disconnect the listener for the <code>element-added</code> signal\n     *\n     * @param listener The listener that was registered to receive the signal.\n     */\n    public void disconnect(ELEMENT_ADDED listener) {\n        disconnect(ELEMENT_ADDED.class, listener);\n    }\n\n    /**\n     * Signal emitted when an {@link Element} is removed from this Bin\n     *\n     * @see #connect(ELEMENT_REMOVED)\n     * @see #disconnect(ELEMENT_REMOVED)\n     */\n    public static interface ELEMENT_REMOVED {\n\n        /**\n         * Called when an {@link Element} is removed from a {@link Bin}\n         *\n         * @param bin the Bin the element was removed from.\n         * @param element the {@link Element} that was removed.\n         */\n        public void elementRemoved(Bin bin, Element element);\n    }\n\n    /**\n     * Add a listener for the <code>element-removed</code> signal on this Bin\n     *\n     * @param listener The listener to be called when an {@link Element} is\n     * removed.\n     */\n    public void connect(final ELEMENT_REMOVED listener) {\n        connect(ELEMENT_REMOVED.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(Bin bin, Element elem) {\n                listener.elementRemoved(bin, elem);\n            }\n        });\n    }\n\n    /**\n     * Disconnect the listener for the <code>element-removed</code> signal\n     *\n     * @param listener The listener that was registered to receive the signal.\n     */\n    public void disconnect(ELEMENT_REMOVED listener) {\n        disconnect(ELEMENT_REMOVED.class, listener);\n    }\n\n    /**\n     * Signal emitted when an {@link Element} is added to sub-bin of this\n     * {@link Bin}\n     *\n     * @see #connect(DEEP_ELEMENT_ADDED)\n     * @see #disconnect(DEEP_ELEMENT_ADDED)\n     */\n    @Gst.Since(minor = 10)\n    public static interface DEEP_ELEMENT_ADDED {\n\n        /**\n         * Called when an {@link Element} is added to a {@link Bin}\n         *\n         * Since GStreamer 1.10\n         *\n         * @param bin the Bin\n         * @param sub_bin the Bin the element was added to.\n         * @param element the {@link Element} that was added.\n         */\n        public void elementAdded(Bin bin, Bin sub_bin, Element element);\n    }\n\n    /**\n     * Add a listener for the <code>deep-element-added</code> signal on this Bin\n     *\n     * @param listener The listener to be called when an {@link Element} is\n     * added.\n     */\n    @Gst.Since(minor = 10)\n    public void connect(final DEEP_ELEMENT_ADDED listener) {\n        Gst.checkVersion(1, 10);\n        connect(DEEP_ELEMENT_ADDED.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(Bin bin, Bin sub_bin, Element elem) {\n                listener.elementAdded(bin, sub_bin, elem);\n            }\n        });\n    }\n\n    /**\n     * Disconnect the listener for the <code>deep-element-added</code> signal\n     *\n     * @param listener The listener that was registered to receive the signal.\n     */\n    @Gst.Since(minor = 10)\n    public void disconnect(DEEP_ELEMENT_ADDED listener) {\n        disconnect(DEEP_ELEMENT_ADDED.class, listener);\n    }\n\n    /**\n     * Signal emitted when an {@link Element} is removed from sub-bin of this\n     * {@link Bin}\n     *\n     * @see #connect(ELEMENT_REMOVED)\n     * @see #disconnect(ELEMENT_REMOVED)\n     */\n    @Gst.Since(minor = 10)\n    public static interface DEEP_ELEMENT_REMOVED {\n\n        /**\n         * Called when an {@link Element} is removed from a {@link Bin}\n         *\n         * Since GStreamer 1.10\n         *\n         * @param bin the Bin\n         * @param sub_bin the Bin the element was removed from.\n         * @param element the {@link Element} that was removed.\n         */\n        public void elementRemoved(Bin bin, Bin sub_bin, Element element);\n    }\n\n    /**\n     * Add a listener for the <code>deep-element-removed</code> signal on this\n     * Bin\n     *\n     * @param listener The listener to be called when an {@link Element} is\n     * removed.\n     */\n    @Gst.Since(minor = 10)\n    public void connect(final DEEP_ELEMENT_REMOVED listener) {\n        Gst.checkVersion(1, 10);\n        connect(DEEP_ELEMENT_REMOVED.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(Bin bin, Bin sub_bin, Element elem) {\n                listener.elementRemoved(bin, sub_bin, elem);\n            }\n        });\n    }\n\n    /**\n     * Disconnect the listener for the <code>deep-element-removed</code> signal\n     *\n     * @param listener The listener that was registered to receive the signal.\n     */\n    @Gst.Since(minor = 10)\n    public void disconnect(DEEP_ELEMENT_REMOVED listener) {\n        disconnect(DEEP_ELEMENT_REMOVED.class, listener);\n    }\n\n    /**\n     * Signal emitted when an {@link Element} has latency\n     *\n     * @see #connect(DO_LATENCY)\n     * @see #disconnect(DO_LATENCY)\n     */\n    public static interface DO_LATENCY {\n\n        /**\n         * Called when an {@link Element} is removed from a {@link Bin}\n         *\n         * @param bin the Bin the element was removed from.\n         */\n        public void doLatency(Bin bin);\n    }\n\n    /**\n     * Add a listener for the <code>do-latency</code> signal on this Bin\n     *\n     * @param listener The listener to be called when an {@link Element} is\n     * removed.\n     */\n    public void connect(final DO_LATENCY listener) {\n        connect(DO_LATENCY.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(Bin bin) {\n                listener.doLatency(bin);\n            }\n        });\n    }\n\n    /**\n     * Disconnect the listener for the <code>do-latency</code> signal\n     *\n     * @param listener The listener that was registered to receive the signal.\n     */\n    public void disconnect(DO_LATENCY listener) {\n        disconnect(DO_LATENCY.class, listener);\n    }\n\n    /**\n     * Available details for pipeline graphs produced by\n     * {@link #debugToDotFile(java.util.EnumSet, java.lang.String)}\n     */\n    public static enum DebugGraphDetails implements NativeFlags<DebugGraphDetails> {\n\n        /**\n         * Show caps-name on edges.\n         */\n        SHOW_MEDIA_TYPE(1 << 0),\n        /**\n         * Show caps-details on edges.\n         */\n        SHOW_CAPS_DETAILS(1 << 1),\n        /**\n         * Show modified parameters on elements.\n         */\n        SHOW_NON_DEFAULT_PARAMS(1 << 2),\n        /**\n         * Show element states.\n         */\n        SHOW_STATES(1 << 3);\n\n        /**\n         * A convenience EnumSet with all values.\n         */\n        public final static EnumSet<DebugGraphDetails> SHOW_ALL\n                = EnumSet.allOf(DebugGraphDetails.class);\n        \n        private final int value;\n\n        private DebugGraphDetails(int value) {\n            this.value = value;\n        }\n\n        @Override\n        public int intValue() {\n            return value;\n        }\n\n    }\n    \n    static class Handle extends Element.Handle {\n        \n        public Handle(GstObjectPtr ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n        \n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/Buffer.java",
    "content": "/*\n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2019 Christophe Lafolet\n * Copyright (C) 2014 Tom Greenwood <tgreenwood@cafex.com>\n * Copyright (C) 2007 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wtay@chello.be>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstBufferAPI.GSTBUFFER_API;\n\nimport java.nio.ByteBuffer;\n\nimport org.freedesktop.gstreamer.lowlevel.GstBufferAPI;\nimport org.freedesktop.gstreamer.lowlevel.GstBufferAPI.BufferStruct;\nimport org.freedesktop.gstreamer.lowlevel.GstBufferAPI.MapInfoStruct;\n\nimport com.sun.jna.Pointer;\nimport com.sun.jna.ptr.PointerByReference;\nimport java.util.EnumSet;\nimport java.util.Iterator;\nimport java.util.NoSuchElementException;\nimport org.freedesktop.gstreamer.glib.NativeFlags;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GType;\nimport org.freedesktop.gstreamer.lowlevel.GstMetaPtr;\n\n/**\n * Buffers are the basic unit of data transfer in GStreamer. They contain the\n * timing and offset along with other arbitrary metadata that is associated with\n * the GstMemory blocks that the buffer contains.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstBuffer.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstBuffer.html</a>\n */\npublic class Buffer extends MiniObject {\n\n    public static final String GTYPE_NAME = \"GstBuffer\";\n\n    private final MapInfoStruct mapInfo;\n    private final BufferStruct struct;\n\n    /**\n     * Creates a newly allocated buffer without any data.\n     */\n    public Buffer() {\n        this(Natives.initializer(GSTBUFFER_API.ptr_gst_buffer_new()));\n    }\n\n    /**\n     * Creates a newly allocated buffer with data of the given size. The buffer\n     * memory is not cleared. If the requested amount of memory cannot be\n     * allocated, an exception will be thrown.\n     * <p>\n     * Note that when size == 0, the buffer data pointer will be NULL.\n     *\n     * @param size\n     */\n    public Buffer(int size) {\n        this(Natives.initializer(allocBuffer(size)));\n    }\n\n    Buffer(Initializer init) {\n        super(init);\n        mapInfo = new MapInfoStruct();\n        struct = new BufferStruct(getRawPointer());\n    }\n\n    private static Pointer allocBuffer(int size) {\n        Pointer ptr = GSTBUFFER_API.ptr_gst_buffer_new_allocate(null, size, null);\n        if (ptr == null) {\n            throw new OutOfMemoryError(\"Could not allocate Buffer of size \" + size);\n        }\n        return ptr;\n    }\n\n    /**\n     * Gets a {@link java.nio.ByteBuffer} that can access the native memory\n     * associated with this Buffer, with the option of ensuring the memory is\n     * writable.\n     * <p>\n     * When requesting a writable buffer, if the buffer is writable but the\n     * underlying memory isn't, a writable copy will automatically be created\n     * and returned. The readonly copy of the buffer memory will then also be\n     * replaced with this writable copy.\n     * <p>\n     * <b>The Buffer should be unmapped with {@link #unmap()} after usage.</b>\n     *\n     * @param writable\n     * @return A {@link java.nio.ByteBuffer} that can access this Buffer's data.\n     */\n    public ByteBuffer map(boolean writable) {\n        final boolean ok = GSTBUFFER_API.gst_buffer_map(this, mapInfo,\n                writable ? GstBufferAPI.GST_MAP_WRITE : GstBufferAPI.GST_MAP_READ);\n        if (ok && mapInfo.data != null) {\n            return mapInfo.data.getByteBuffer(0, mapInfo.size.intValue());\n        }\n        return null;\n    }\n\n    /**\n     * Release the memory previously mapped with {@link #map(boolean)}\n     */\n    public void unmap() {\n        GSTBUFFER_API.gst_buffer_unmap(this, mapInfo);\n    }\n\n    /**\n     * Get the amount of memory blocks that this buffer has. This amount is never\n     * larger than what {@code gst_buffer_get_max_memory()} returns.\n     *\n     * @return the number of memory blocks this buffer is made of.\n     */\n    public int getMemoryCount() {\n        return GSTBUFFER_API.gst_buffer_n_memory(this);\n    }\n\n    /**\n     * Gets the timestamps of this buffer. The buffer DTS refers to the\n     * timestamp when the buffer should be decoded and is usually monotonically\n     * increasing.\n     *\n     * @return a long representing the timestamp or {@link ClockTime#NONE}\n     * when the timestamp is not known or relevant.\n     */\n    public long getDecodeTimestamp() {\n        return (long) this.struct.readField(\"dts\");\n    }\n\n    /**\n     * Set the decode timestamp of the Buffer\n     *\n     * @param val a long representing the timestamp or\n     * {@link ClockTime#NONE} when the timestamp is not known or relevant.\n     */\n    public void setDecodeTimestamp(long val) {\n        this.struct.writeField(\"dts\", val);\n    }\n\n    /**\n     * Gets the timestamps of this buffer. The buffer PTS refers to the\n     * timestamp when the buffer content should be presented to the user and is\n     * not always monotonically increasing.\n     *\n     * @return a long representing the timestamp or {@link ClockTime#NONE}\n     * when the timestamp is not known or relevant.\n     */\n    public long getPresentationTimestamp() {\n        return (long) this.struct.readField(\"pts\");\n    }\n\n    /**\n     * Set the presentation timestamp of the Buffer\n     *\n     * @param val a long representing the timestamp or\n     * {@link ClockTime#NONE} when the timestamp is not known or relevant.\n     */\n    public void setPresentationTimestamp(long val) {\n        this.struct.writeField(\"pts\", val);\n    }\n\n    /**\n     * Gets the duration of this buffer.\n     *\n     * @return a ClockTime representing the timestamp or {@link ClockTime#NONE}\n     * when the timestamp is not known or relevant.\n     */\n    public long getDuration() {\n        return (long) this.struct.readField(\"duration\");\n    }\n\n    /**\n     * Set the duration of this buffer.\n     *\n     * @param val a long representing the duration or\n     * {@link ClockTime#NONE} when the timestamp is not known or relevant.\n     */\n    public void setDuration(long val) {\n        this.struct.writeField(\"duration\", val);\n    }\n\n    /**\n     * Get the offset (media-specific) of this buffer\n     *\n     * @return a media specific offset for the buffer data. For video frames,\n     * this is the frame number of this buffer. For audio samples, this is the\n     * offset of the first sample in this buffer. For file data or compressed\n     * data this is the byte offset of the first byte in this buffer.\n     */\n    public long getOffset() {\n        return (Long) this.struct.readField(\"offset\");\n    }\n\n    /**\n     * Set the offset (media-specific) of this buffer\n     *\n     * @param val a media specific offset for the buffer data. For video frames,\n     * this is the frame number of this buffer. For audio samples, this is the\n     * offset of the first sample in this buffer. For file data or compressed\n     * data this is the byte offset of the first byte in this buffer.\n     */\n    public void setOffset(long val) {\n        this.struct.writeField(\"offset\", val);\n    }\n\n    /**\n     * Get the offset (media-specific) of this buffer\n     *\n     * @return a media specific offset for the buffer data. For video frames,\n     * this is the frame number of this buffer. For audio samples, this is the\n     * offset of the first sample in this buffer. For file data or compressed\n     * data this is the byte offset of the first byte in this buffer.\n     */\n    public long getOffsetEnd() {\n        return (Long) this.struct.readField(\"offset_end\");\n    }\n\n    /**\n     * Set the offset (media-specific) of this buffer\n     *\n     * @param val a media specific offset for the buffer data. For video frames,\n     * this is the frame number of this buffer. For audio samples, this is the\n     * offset of the first sample in this buffer. For file data or compressed\n     * data this is the byte offset of the first byte in this buffer.\n     */\n    public void setOffsetEnd(long val) {\n        this.struct.writeField(\"offset_end\", val);\n    }\n\n    /**\n     * Get the GstBufferFlags describing this buffer.\n     * <p>\n     * Since GStreamer 1.10\n     *\n     * @return an EnumSet of {@link BufferFlags}\n     */\n    @Gst.Since(minor = 10)\n    public EnumSet<BufferFlags> getFlags() {\n        Gst.checkVersion(1, 10);\n        int nativeInt = GstBufferAPI.GSTBUFFER_API.gst_buffer_get_flags(this);\n        return NativeFlags.fromInt(BufferFlags.class, nativeInt);\n    }\n\n    /**\n     * Get the metadata for api on buffer. When there is no such metadata, NULL\n     * is returned.\n     *\n     * @param <T> implementation type of metadata\n     * @param api api type of metadata\n     * @return meta or null\n     */\n    public <T extends Meta> T getMeta(Meta.API<T> api) {\n        GType apiType = api.getAPIGType();\n        if (apiType == GType.INVALID) {\n            return null;\n        }\n        GstMetaPtr ptr = GSTBUFFER_API.gst_buffer_get_meta(this, apiType);\n        // can not create metadata class from null pointer\n        if (ptr == null) {\n            return null;\n        }\n        return Natives.objectFor(ptr, api.getImplClass(), false, false);\n    }\n    \n    /**\n     * Iterate all Meta on buffer.\n     * \n     * @return iterator of meta\n     */\n    public Iterator<Meta> iterateMeta() {\n        return new MetaIterator(this);\n    }\n\n    /**\n     * Check if buffer contains metadata for api.\n     * <p>\n     * Since GStreamer 1.14\n     *\n     * @param <T> implementation type of metadata\n     * @param api type of metadata\n     * @return return true only if buffer contains selected type of metadata\n     */\n    @Gst.Since(minor = 14)\n    public <T extends Meta> boolean hasMeta(Meta.API<T> api) {\n        return getMetaCount(api) > 0;\n    }\n\n    /**\n     * Check number of metadata for api. There can be more than one metadata in\n     * case of multiple video/audio layer.\n     * <p>\n     * Since GStreamer 1.14\n     *\n     * @param <T> implementation type of metadata\n     * @param api type of metadata\n     * @return count of metadata of provided api type\n     */\n    @Gst.Since(minor = 14)\n    public <T extends Meta> int getMetaCount(Meta.API<T> api) {\n        Gst.checkVersion(1, 14);\n        GType apiType = api.getAPIGType();\n        if (apiType == GType.INVALID) {\n            return 0;\n        }\n        return GSTBUFFER_API.gst_buffer_get_n_meta(this, apiType);\n    }\n\n\n    /**\n     * Set some of the GstBufferFlags describing this buffer. This is a union\n     * operation and does not clear flags that are not mentioned.\n     * <p>\n     * Since GStreamer 1.10\n     *\n     * @param flags an EnumSet of {@link BufferFlags} to be set on the buffer.\n     * @return true if flags were successfully set on this buffer\n     */\n    @Gst.Since(minor = 10)\n    public boolean setFlags(EnumSet<BufferFlags> flags) {\n        Gst.checkVersion(1, 10);\n        return GstBufferAPI.GSTBUFFER_API.gst_buffer_set_flags(this, NativeFlags.toInt(flags));\n    }\n\n    /**\n     * unset the GstBufferFlags describing this buffer. This is a difference\n     * operation and does not clear flags that are not mentioned.\n     * <p>\n     * Since GStreamer 1.10\n     *\n     * @param flags an EnumSet of {@link BufferFlags} to be cleared on the buffer.\n     * @return true if flags were successfully cleared on this buffer\n     *\n     */\n    @Gst.Since(minor = 10)\n    public boolean unsetFlags(EnumSet<BufferFlags> flags) {\n        Gst.checkVersion(1, 10);\n        return GstBufferAPI.GSTBUFFER_API.gst_buffer_unset_flags(this, NativeFlags.toInt(flags));\n    }\n\n    private static class MetaIterator implements Iterator<Meta> {\n\n        private final PointerByReference state;\n        private final Buffer buffer;\n        private Meta next;\n\n        MetaIterator(final Buffer buffer) {\n            state = new PointerByReference();\n            this.buffer = buffer;\n        }\n\n        @Override\n        public boolean hasNext() {\n            if (next == null) {\n                next = getNext();\n            }\n            return next != null;\n        }\n        \n        @Override\n        public Meta next() {\n            if (!hasNext() || next == null) {\n                throw new NoSuchElementException();\n            }\n            Meta m = next;\n            next = null;\n            return m;\n        }\n\n        private Meta getNext() {\n            return Natives.objectFor(\n                    GSTBUFFER_API.gst_buffer_iterate_meta(this.buffer, this.state),\n                    Meta.class,\n                    false,\n                    false\n            );\n        }\n\n\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/BufferFlags.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (C) 2007 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wtay@chello.be>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.NativeFlags;\n\n/**\n * A set of buffer flags used to describe properties of a {@link Buffer}.\n */\npublic enum BufferFlags implements NativeFlags<BufferFlags> {\n\n    /**  \n     * the {@link Buffer} is live data and should be discarded in the PAUSED state.\n     */\n    LIVE(MiniObjectFlags.LAST.intValue() << 0),\n\n    /**\n     * the {@link Buffer} contains data that should be dropped\n     * because it will be clipped against the segment\n     * boundaries or because it does not contain data\n     * that should be shown to the user.\n     */\n    DECODE_ONLY(MiniObjectFlags.LAST.intValue() << 1),\n\n    /**\n     * The {@link Buffer} marks a discontinuity in the stream.\n     * This typically occurs after a seek or a dropped buffer from a live or\n     * network source.\n     */\n    DISCONT(MiniObjectFlags.LAST.intValue() << 2),\n\n    /**\n     * The {@link Buffer} timestamps might have a discontinuity and this buffer is a good point to resynchronize.\n     */\n    RESYNC(MiniObjectFlags.LAST.intValue() << 3),\n\n    /**\n     * the {@link Buffer} data is corrupted.\n     */\n    CORRUPTED(MiniObjectFlags.LAST.intValue() << 4),\n\n    /**\n     * 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.\n     */\n    MARKER(MiniObjectFlags.LAST.intValue() << 5),\n\n    /**\n     * he buffer contains header information that is needed to decode the following data.\n     */\n    HEADER(MiniObjectFlags.LAST.intValue() << 6),\n\n    /**\n     * The {@link Buffer} has been created to fill a gap in the\n     * stream and contains media neutral data (elements can switch to optimized code\n     * path that ignores the buffer content).\n     */\n    GAP(MiniObjectFlags.LAST.intValue() << 7),\n\n    /**\n     * the {@link Buffer} can be dropped without breaking the stream, for example to reduce bandwidth.\n     */\n    DROPPABLE(MiniObjectFlags.LAST.intValue() << 8),\n    \n    /** This unit cannot be decoded independently. */\n    DELTA_UNIT(MiniObjectFlags.LAST.intValue() << 9),\n\n    /**\n     * this flag is set when memory of the {@link Buffer} is added/removed\n     */\n    TAG_MEMORY(MiniObjectFlags.LAST.intValue() << 10),\n\n    /**\n     * 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)\n     */\n    SYNC_AFTER(MiniObjectFlags.LAST.intValue() << 11),\n    \n    /**\n     * This buffer is important and should not be dropped. This can be used to\n     * mark important buffers, e.g. to flag RTP packets carrying keyframes or\n     * codec setup data for RTP Forward Error Correction purposes, or to prevent\n     * still video frames from being dropped by elements due to QoS. (Since\n     * 1.14)\n\n     */\n    @Gst.Since(minor = 14)\n    NON_DROPPABLE(MiniObjectFlags.LAST.intValue() << 12),\n    \n    /* padding */\n    LAST(MiniObjectFlags.LAST.intValue() << 16);\n    \n    private final int value;\n    \n    private BufferFlags(int value) {\n        this.value = value;\n    }\n    /**\n     * Get the integer value of the enum.\n     * @return The integer value for this enum.\n     */\n    public final int intValue() {\n        return value;\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/BufferPool.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2016 Christophe Lafolet\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.lowlevel.GstBufferPoolAPI;\n\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.glib.Natives;\n\n/**\n * A BufferPool is an object that can be used to pre-allocate and recycle\n * buffers of the same size and with the same properties.\n * <p>\n *  See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstBufferPool.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstBufferPool.html</a>\n */\npublic class BufferPool extends GstObject {\n\n    public static final String GTYPE_NAME = \"GstBufferPool\";\n\n    /**\n     * Creates a new instance of BufferPool\n     */\n    public BufferPool() {\n        this(Natives.initializer(GstBufferPoolAPI.GSTBUFFERPOOL_API.ptr_gst_buffer_pool_new()));\n    }\n    \n    /**\n     * This constructor is for internal use only.\n     * @param init initialization data.\n     */\n    BufferPool(final Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Configure the BufferPool with the given parameters.\n     * \n     * @param caps the {@link Caps} for the buffers\n     * @param size the size of each buffer, not including prefix and padding\n     * @param min_buffers the minimum amount of buffers to allocate\n     * @param max_buffers the maximum amount of buffers to allocate or 0 for unlimited\n     */\n    public void setParams(Caps caps, int size, int min_buffers, int max_buffers) {\n    \tStructure config = GstBufferPoolAPI.GSTBUFFERPOOL_API.gst_buffer_pool_get_config(this);\n    \tGstBufferPoolAPI.GSTBUFFERPOOL_API.gst_buffer_pool_config_set_params(config, caps, size, min_buffers, max_buffers);\n    }\n\n    /**\n     * Query the {@link Caps} configured on the BufferPool.\n     * \n     * @return Caps configured on the BufferPool\n     */\n    public Caps getCaps() {\n    \tStructure config = GstBufferPoolAPI.GSTBUFFERPOOL_API.gst_buffer_pool_get_config(this);\n    \tPointer[] ptr = new Pointer[1];\n    \tGstBufferPoolAPI.GSTBUFFERPOOL_API.gst_buffer_pool_config_get_params(config, ptr, null, null, null);\n    \treturn new Caps(Natives.initializer(ptr[0], false, true));\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/Bus.java",
    "content": "/* \n * Copyright (c) 2025 Neil C Smith\n * Copyright (C) 2014 Tom Greenwood <tgreenwood@cafex.com>\n * Copyright (C) 2007 Wayne Meissner\n * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport java.util.List;\nimport java.util.Locale;\nimport java.util.concurrent.CopyOnWriteArrayList;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\nimport com.sun.jna.Callback;\nimport com.sun.jna.CallbackThreadInitializer;\nimport com.sun.jna.Native;\nimport com.sun.jna.Pointer;\nimport com.sun.jna.ptr.IntByReference;\nimport com.sun.jna.ptr.LongByReference;\nimport com.sun.jna.ptr.PointerByReference;\nimport org.freedesktop.gstreamer.glib.GObject;\nimport org.freedesktop.gstreamer.glib.NativeEnum;\n\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GErrorStruct;\nimport org.freedesktop.gstreamer.lowlevel.GstBusAPI;\nimport org.freedesktop.gstreamer.lowlevel.GstBusAPI.BusCallback;\nimport org.freedesktop.gstreamer.lowlevel.GstBusPtr;\nimport org.freedesktop.gstreamer.lowlevel.GstMessagePtr;\nimport org.freedesktop.gstreamer.message.Message;\nimport org.freedesktop.gstreamer.message.MessageType;\n\nimport static org.freedesktop.gstreamer.lowlevel.GlibAPI.GLIB_API;\nimport static org.freedesktop.gstreamer.lowlevel.GstBusAPI.GSTBUS_API;\nimport static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API;\nimport static org.freedesktop.gstreamer.lowlevel.GstMiniObjectAPI.GSTMINIOBJECT_API;\n\n/**\n * The {@link Bus} is an object responsible for delivering {@link Message}s in a\n * first-in first-out way from the streaming threads to the application.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/documentation/gstreamer/gstbus.html\"\n * >https://gstreamer.freedesktop.org/documentation/gstreamer/gstbus.html</a>\n * <p>\n * Since the application typically only wants to deal with delivery of these\n * messages from one thread, the Bus will marshal the messages between different\n * threads. This is important since the actual streaming of media is done in\n * another thread than the application.\n * <p>\n * It is also possible to get messages from the bus without any thread\n * marshalling with the {@link #setSyncHandler} method. This makes it possible\n * to react to a message in the same thread that posted the message on the bus.\n * This should only be used if the application is able to deal with messages\n * from different threads.\n * <p>\n * Every {@link Pipeline} has one bus.\n * <p>\n * Note that a Pipeline will set its bus into flushing state when changing from\n * READY to NULL state.\n */\npublic class Bus extends GstObject {\n\n    public static final String GTYPE_NAME = \"GstBus\";\n\n    private static final Logger LOG = Logger.getLogger(Bus.class.getName());\n    private static final SyncCallback SYNC_CALLBACK = new SyncCallback();\n\n    private volatile BusSyncHandler syncHandler = null;\n\n    private final Object lock = new Object();\n    private final List<MessageProxy<?>> messageProxies = new CopyOnWriteArrayList<>();\n    private boolean watchAdded = false;\n\n    /**\n     * This constructor is used internally by gstreamer-java\n     *\n     * @param init internal initialization data\n     */\n    Bus(Initializer init) {\n        super(init);\n        GSTBUS_API.gst_bus_set_sync_handler(this, null, null, null);\n        GSTBUS_API.gst_bus_set_sync_handler(this, SYNC_CALLBACK, null, null);\n    }\n\n    /**\n     * Instructs the bus to flush out any queued messages.\n     *\n     * If flushing, flush out any messages queued in the bus. Will flush future\n     * messages until {@link #setFlushing} is called with false.\n     *\n     * @param flushing true if flushing is desired.\n     */\n    public void setFlushing(boolean flushing) {\n        GSTBUS_API.gst_bus_set_flushing(this, flushing ? 1 : 0);\n    }\n\n    /**\n     * Add a listener for end-of-stream messages.\n     *\n     * @param listener The listener to be called when end-of-stream is\n     * encountered.\n     */\n    public void connect(final EOS listener) {\n        connect(EOS.class, listener, new BusCallback() {\n            public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) {\n                listener.endOfStream(Natives.objectFor(msg.getSource(), GstObject.class, true, true));\n                return true;\n            }\n        });\n    }\n\n    /**\n     * Disconnect the listener for end-of-stream messages.\n     *\n     * @param listener The listener that was registered to receive the message.\n     */\n    public void disconnect(EOS listener) {\n        disconnect(EOS.class, listener);\n    }\n\n    /**\n     * Add a listener for error messages.\n     *\n     * @param listener The listener to be called when an error in the stream is\n     * encountered.\n     */\n    public void connect(final ERROR listener) {\n        connect(ERROR.class, listener, new BusCallback() {\n            public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) {\n                PointerByReference err = new PointerByReference();\n                GSTMESSAGE_API.gst_message_parse_error(msg, err, null);\n                GErrorStruct error = new GErrorStruct(err.getValue());\n                GstObject source = Natives.objectFor(msg.getSource(), GstObject.class, true, true);\n                listener.errorMessage(source, error.getCode(), error.getMessage());\n                GLIB_API.g_error_free(err.getValue());\n                return true;\n            }\n        });\n    }\n\n    /**\n     * Disconnect the listener for error messages.\n     *\n     * @param listener The listener that was registered to receive the message.\n     */\n    public void disconnect(ERROR listener) {\n        disconnect(ERROR.class, listener);\n    }\n\n    /**\n     * Add a listener for warning messages.\n     *\n     * @param listener The listener to be called when an {@link Element} emits a\n     * warning.\n     */\n    public void connect(final WARNING listener) {\n        connect(WARNING.class, listener, new BusCallback() {\n            public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) {\n                PointerByReference err = new PointerByReference();\n                GSTMESSAGE_API.gst_message_parse_warning(msg, err, null);\n                GErrorStruct error = new GErrorStruct(err.getValue());\n                GstObject source = Natives.objectFor(msg.getSource(), GstObject.class, true, true);\n                listener.warningMessage(source, error.getCode(), error.getMessage());\n                GLIB_API.g_error_free(err.getValue());\n                return true;\n            }\n        });\n    }\n\n    /**\n     * Disconnect the listener for warning messages.\n     *\n     * @param listener The listener that was registered to receive the message.\n     */\n    public void disconnect(WARNING listener) {\n        disconnect(WARNING.class, listener);\n    }\n\n    /**\n     * Add a listener for informational messages.\n     *\n     * @param listener The listener to be called when an {@link Element} emits a\n     * an informational message.\n     */\n    public void connect(final INFO listener) {\n        connect(INFO.class, listener, new BusCallback() {\n            public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) {\n                PointerByReference err = new PointerByReference();\n                GSTMESSAGE_API.gst_message_parse_info(msg, err, null);\n                GErrorStruct error = new GErrorStruct(err.getValue());\n                GstObject source = Natives.objectFor(msg.getSource(), GstObject.class, true, true);\n                listener.infoMessage(source, error.getCode(), error.getMessage());\n                GLIB_API.g_error_free(err.getValue());\n                return true;\n            }\n        });\n    }\n\n    /**\n     * Disconnect the listener for informational messages.\n     *\n     * @param listener The listener that was registered to receive the message.\n     */\n    public void disconnect(INFO listener) {\n        disconnect(INFO.class, listener);\n    }\n\n    /**\n     * Add a listener for {@link State} changes in the Pipeline.\n     *\n     * @param listener The listener to be called when the Pipeline changes\n     * state.\n     */\n    public void connect(final STATE_CHANGED listener) {\n        connect(STATE_CHANGED.class, listener, new BusCallback() {\n            public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) {\n                IntByReference oldPtr = new IntByReference();\n                IntByReference currentPtr = new IntByReference();\n                IntByReference pendingPtr = new IntByReference();\n                GSTMESSAGE_API.gst_message_parse_state_changed(msg, oldPtr, currentPtr, pendingPtr);\n                State old = NativeEnum.fromInt(State.class, oldPtr.getValue());\n                State current = NativeEnum.fromInt(State.class, currentPtr.getValue());\n                State pending = NativeEnum.fromInt(State.class, pendingPtr.getValue());\n                GstObject source = Natives.objectFor(msg.getSource(), GstObject.class, true, true);\n                listener.stateChanged(source, old, current, pending);\n                return true;\n            }\n        });\n    }\n\n    /**\n     * Disconnect the listener for {@link State} change messages.\n     *\n     * @param listener The listener that was registered to receive the message.\n     */\n    public void disconnect(STATE_CHANGED listener) {\n        disconnect(STATE_CHANGED.class, listener);\n    }\n\n    /**\n     * Add a listener for new media tags.\n     *\n     * @param listener The listener to be called when new media tags are found.\n     */\n    public void connect(final TAG listener) {\n        connect(TAG.class, listener, new BusCallback() {\n            public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) {\n                PointerByReference list = new PointerByReference();\n                GSTMESSAGE_API.gst_message_parse_tag(msg, list);\n                TagList tl = new TagList(Natives.initializer(list.getValue()));\n                GstObject source = Natives.objectFor(msg.getSource(), GstObject.class, true, true);\n                listener.tagsFound(source, tl);\n                return true;\n            }\n        });\n    }\n\n    /**\n     * Disconnect the listener for tag messages.\n     *\n     * @param listener The listener that was registered to receive the message.\n     */\n    public void disconnect(TAG listener) {\n        disconnect(TAG.class, listener);\n    }\n\n    /**\n     * Add a listener for {@link BUFFERING} messages in the Pipeline.\n     *\n     * @param listener The listener to be called when the Pipeline buffers data.\n     */\n    public void connect(final BUFFERING listener) {\n        connect(BUFFERING.class, listener, new BusCallback() {\n            public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) {\n                IntByReference percent = new IntByReference();\n                GSTMESSAGE_API.gst_message_parse_buffering(msg, percent);\n                GstObject source = Natives.objectFor(msg.getSource(), GstObject.class, true, true);\n                listener.bufferingData(source, percent.getValue());\n                return true;\n            }\n        });\n    }\n\n    /**\n     * Disconnect the listener for buffering messages.\n     *\n     * @param listener The listener that was registered to receive the message.\n     */\n    public void disconnect(BUFFERING listener) {\n        disconnect(BUFFERING.class, listener);\n    }\n\n    /**\n     * Add a listener for duration changes.\n     *\n     * @param listener The listener to be called when the duration changes.\n     */\n    public void connect(final DURATION_CHANGED listener) {\n        connect(DURATION_CHANGED.class, listener, new BusCallback() {\n            public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) {\n                GstObject source = Natives.objectFor(msg.getSource(), GstObject.class, true, true);\n                listener.durationChanged(source);\n                return true;\n            }\n        });\n    }\n\n    /**\n     * Disconnect the listener for duration change messages.\n     *\n     * @param listener The listener that was registered to receive the message.\n     */\n    public void disconnect(DURATION_CHANGED listener) {\n        disconnect(DURATION_CHANGED.class, listener);\n    }\n\n    /**\n     * Add a listener for {@link SEGMENT_START} messages in the Pipeline.\n     *\n     * @param listener The listener to be called when the Pipeline has started a\n     * segment.\n     */\n    public void connect(final SEGMENT_START listener) {\n        connect(SEGMENT_START.class, listener, new BusCallback() {\n            public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) {\n                IntByReference formatPtr = new IntByReference();\n                LongByReference positionPtr = new LongByReference();\n                GSTMESSAGE_API.gst_message_parse_segment_start(msg, formatPtr, positionPtr);\n                Format format = NativeEnum.fromInt(Format.class, formatPtr.getValue());\n                GstObject source = Natives.objectFor(msg.getSource(), GstObject.class, true, true);\n                listener.segmentStart(source, format, positionPtr.getValue());\n                return true;\n            }\n        });\n    }\n\n    /**\n     * Disconnect the listener for segment-start messages.\n     *\n     * @param listener The listener that was registered to receive the message.\n     */\n    public void disconnect(SEGMENT_START listener) {\n        disconnect(SEGMENT_START.class, listener);\n    }\n\n    /**\n     * Add a listener for {@link SEGMENT_DONE} messages in the Pipeline.\n     *\n     * @param listener The listener to be called when the Pipeline has finished\n     * a segment.\n     */\n    public void connect(final SEGMENT_DONE listener) {\n        connect(SEGMENT_DONE.class, listener, new BusCallback() {\n            public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) {\n                IntByReference formatPtr = new IntByReference();\n                LongByReference positionPtr = new LongByReference();\n                GSTMESSAGE_API.gst_message_parse_segment_done(msg, formatPtr, positionPtr);\n                Format format = NativeEnum.fromInt(Format.class, formatPtr.getValue());\n                GstObject source = Natives.objectFor(msg.getSource(), GstObject.class, true, true);\n                listener.segmentDone(source, format, positionPtr.getValue());\n                return true;\n            }\n        });\n    }\n\n    /**\n     * Disconnect the listener for segment-done messages.\n     *\n     * @param listener The listener that was registered to receive the message.\n     */\n    public void disconnect(SEGMENT_DONE listener) {\n        disconnect(SEGMENT_DONE.class, listener);\n    }\n\n    /**\n     * Add a listener for {@link ASYNC_DONE} messages in the Pipeline.\n     *\n     * @param listener The listener to be called when the an element has\n     * finished an async state change.\n     */\n    public void connect(final ASYNC_DONE listener) {\n        connect(ASYNC_DONE.class, listener, new BusCallback() {\n            public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) {\n                GstObject source = Natives.objectFor(msg.getSource(), GstObject.class, true, true);\n                listener.asyncDone(source);\n                return true;\n            }\n        });\n    }\n\n    /**\n     * Disconnect the listener for async-done messages.\n     *\n     * @param listener The listener that was registered to receive the message.\n     */\n    public void disconnect(ASYNC_DONE listener) {\n        disconnect(ASYNC_DONE.class, listener);\n    }\n\n    /**\n     * Add a listener for all messages posted on the Bus.\n     *\n     * @param listener The listener to be called when a {@link Message} is\n     * posted.\n     */\n    public void connect(final MESSAGE listener) {\n        connect(MESSAGE.class, listener, new BusCallback() {\n            public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) {\n                listener.busMessage(Bus.this, Natives.objectFor(msg, Message.class, true, true));\n                return true;\n            }\n        });\n    }\n\n    /**\n     * Add a listener for messages of type {@code signal} posted on the Bus.\n     *\n     * @param signal the signal to connect to.\n     * @param listener The listener to be called when a {@link Message} is\n     * posted.\n     */\n    public void connect(String signal, final MESSAGE listener) {\n        //\n        // Deal with being called as e.g. \"message::eos\"\n        //\n        if (signal.contains(\"::\")) {\n            signal = signal.substring(signal.lastIndexOf(\"::\") + 2);\n        }\n        connect(signal, MESSAGE.class, listener, new BusCallback() {\n            public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) {\n                listener.busMessage(Bus.this, Natives.objectFor(msg, Message.class, true, true));\n                return true;\n            }\n        });\n    }\n\n    /**\n     * Disconnect the listener for segment-done messages.\n     *\n     * @param listener The listener that was registered to receive the message.\n     */\n    public void disconnect(MESSAGE listener) {\n        disconnect(MESSAGE.class, listener);\n    }\n\n    /**\n     * Posts a {@link Message} on this Bus.\n     *\n     * @param message the message to post.\n     * @return <tt>true</tt> if the message could be posted, <tt>false</tt> if\n     * the bus is flushing.\n     */\n    public boolean post(Message message) {\n        return GSTBUS_API.gst_bus_post(this, message);\n    }\n\n    /**\n     * Sets the synchronous handler (message listener) on the bus. The handler\n     * will be called every time a new message is posted on the bus. Note that\n     * the handler will be called in the same thread context as the posting\n     * object. Applications should generally handle messages asynchronously\n     * using the other message listeners.\n     * <p>\n     * Only one handler may be attached to the bus at any one time. An attached\n     * sync handler forces creation of {@link Message} objects for all messages\n     * on the bus, so the handler should be removed if no longer required.\n     * <p>\n     * A single native sync handler is used at all times, with synchronous and\n     * asynchronous dispatch handled on the Java side, so the bindings do not\n     * inherit issues in clearing or replacing the sync handler with versions of\n     * GStreamer prior to 1.16.3.\n     *\n     * @param handler bus sync handler, or null to remove\n     */\n    public void setSyncHandler(BusSyncHandler handler) {\n        syncHandler = handler;\n    }\n\n    /**\n     * Clear the synchronous handler.\n     * <p>\n     * This is a convenience method equivalent to {@code setSyncHandler(null)}\n     */\n    public void clearSyncHandler() {\n        setSyncHandler(null);\n    }\n\n    /**\n     * Get the current synchronous handler.\n     *\n     * @return current sync handler, or null\n     */\n    public BusSyncHandler getSyncHandler() {\n        return syncHandler;\n    }\n\n    /**\n     * Connects to a signal.\n     *\n     * The signal name is deduced from the listenerClass name.\n     *\n     * @param listenerClass the class of the listener.\n     * @param listener the listener to associate with the {@code callback}\n     * @param callback The callback to call when the signal is emitted.\n     */\n    private <T> void connect(Class<T> listenerClass, T listener, BusCallback callback) {\n        String className = listenerClass.getSimpleName();\n        MessageType type;\n        if (\"MESSAGE\".equals(className)) {\n            type = MessageType.ANY;\n        } else {\n            type = MessageType.valueOf(listenerClass.getSimpleName());\n        }\n        addMessageProxy(type, listenerClass, listener, callback);\n    }\n\n    /**\n     * Connects a callback to a signal.\n     * <p>\n     * This differs to {@link GObject#connect} in that it hooks up Bus signals\n     * to the sync callback, not the generic GObject signal mechanism.\n     *\n     * @param <T> listener type\n     * @param signal the name of the signal to connect to.\n     * @param listenerClass the class of the {@code listener}\n     * @param listener the listener to associate with the {@code callback}\n     * @param callback the callback to call when the signal is emitted.\n     */\n    @Override\n    public <T> void connect(String signal, Class<T> listenerClass, T listener,\n            final Callback callback) {\n        if (listenerClass.getEnclosingClass() != Bus.class) {\n            super.connect(signal, listenerClass, listener, callback);\n        } else {\n            MessageType type;\n            if (\"message\".equals(signal)) {\n                type = MessageType.ANY;\n            } else {\n                type = MessageType.valueOf(signal.toUpperCase(Locale.ROOT).replace('-', '_'));\n            }\n            addMessageProxy(type, listenerClass, listener, (BusCallback) callback);\n        }\n    }\n\n    private synchronized <T> void addMessageProxy(MessageType type,\n            Class<T> listenerClass,\n            T listener,\n            BusCallback callback) {\n        messageProxies.add(new MessageProxy(type, listenerClass, listener, callback));\n        addWatch();\n    }\n\n    @Override\n    public <T> void disconnect(Class<T> listenerClass, T listener) {\n        if (listenerClass.getEnclosingClass() != Bus.class) {\n            super.disconnect(listenerClass, listener);\n        } else {\n            removeMessageProxy(listenerClass, listener);\n        }\n    }\n\n    private synchronized <T> void removeMessageProxy(Class<T> listenerClass, T listener) {\n        messageProxies.removeIf(p -> p.listener == listener);\n        if (messageProxies.isEmpty()) {\n            removeWatch();\n        }\n    }\n\n    /**\n     * Dispatches a message to all interested listeners.\n     * <p>\n     * We do this here from a sync callback, because the default gstbus dispatch\n     * uses the default main context to signal that there are messages waiting\n     * on the bus. Since that is used by the GTK L&F under swing, we never get\n     * those notifications, and the messages just queue up.\n     *\n     */\n    private void dispatchMessage(GstBusPtr busPtr, GstMessagePtr msgPtr) {\n        messageProxies.forEach(p -> {\n            try {\n                p.busMessage(busPtr, msgPtr);\n            } catch (Throwable t) {\n                LOG.log(Level.SEVERE, \"Exception thrown by bus message handler\", t);\n            }\n        });\n        GSTMINIOBJECT_API.gst_mini_object_unref(msgPtr);\n    }\n\n    @Override\n    public void dispose() {\n        removeWatch();\n        super.dispose();\n    }\n\n    /**\n     * Adds the bus signal watch. This will reference the bus until the signal\n     * watch is removed and so will stop the Bus being GC'd and disposed.\n     */\n    private void addWatch() {\n        synchronized (lock) {\n            if (!watchAdded) {\n                LOG.fine(\"Add watch\");\n                GSTBUS_API.gst_bus_add_signal_watch(this);\n                watchAdded = true;\n            }\n        }\n    }\n\n    /**\n     * Removes the bus signal watch (which will remove the bus reference held by\n     * the signal watch).\n     */\n    private void removeWatch() {\n        synchronized (lock) {\n            if (watchAdded) {\n                LOG.fine(\"Remove watch\");\n                GSTBUS_API.gst_bus_remove_signal_watch(this);\n                watchAdded = false;\n            }\n        }\n    }\n\n    /**\n     * Signal emitted when end-of-stream is reached in a pipeline.\n     *\n     * The application will only receive this message in the PLAYING state and\n     * every time it sets a pipeline to PLAYING that is in the EOS state. The\n     * application can perform a flushing seek in the pipeline, which will undo\n     * the EOS state again.\n     *\n     * @see #connect(EOS)\n     * @see #disconnect(EOS)\n     */\n    public static interface EOS {\n\n        /**\n         * Called when a {@link Pipeline} element posts a end-of-stream message.\n         *\n         * @param source the element which posted the message.\n         */\n        public void endOfStream(GstObject source);\n    }\n\n    /**\n     * Signal emitted when an error occurs.\n     * <p>\n     * When the application receives an error message it should stop playback of\n     * the pipeline and not assume that more data will be played.\n     *\n     * @see #connect(ERROR)\n     * @see #disconnect(ERROR)\n     */\n    public static interface ERROR {\n\n        /**\n         * Called when a {@link Pipeline} element posts an error message.\n         *\n         * @param source the element which posted the message.\n         * @param code a numeric code representing the error.\n         * @param message a string representation of the error.\n         */\n        public void errorMessage(GstObject source, int code, String message);\n    }\n\n    /**\n     * Signal emitted when a warning message is delivered.\n     *\n     * @see #connect(WARNING)\n     * @see #disconnect(WARNING)\n     */\n    public static interface WARNING {\n\n        /**\n         * Called when a {@link Pipeline} element posts an warning message.\n         *\n         * @param source the element which posted the message.\n         * @param code a numeric code representing the warning.\n         * @param message a string representation of the warning.\n         */\n        public void warningMessage(GstObject source, int code, String message);\n    }\n\n    /**\n     * Signal emitted when an informational message is delivered.\n     *\n     * @see #connect(INFO)\n     * @see #disconnect(INFO)\n     */\n    public static interface INFO {\n\n        /**\n         * Called when a {@link Pipeline} element posts an informational\n         * message.\n         *\n         * @param source the element which posted the message.\n         * @param code a numeric code representing the informational message.\n         * @param message a string representation of the informational message.\n         */\n        public void infoMessage(GstObject source, int code, String message);\n    }\n\n    /**\n     * Signal emitted when a new tag is identified on the stream.\n     *\n     * @see #connect(TAG)\n     * @see #disconnect(TAG)\n     */\n    public static interface TAG {\n\n        /**\n         * Called when a {@link Pipeline} element finds media meta-data.\n         *\n         * @param source the element which posted the message.\n         * @param tagList a list of media meta-data.\n         */\n        public void tagsFound(GstObject source, TagList tagList);\n    }\n\n    /**\n     * Signal emitted when a state change happens.\n     *\n     * @see #connect(STATE_CHANGED)\n     * @see #disconnect(STATE_CHANGED)\n     */\n    public static interface STATE_CHANGED {\n\n        /**\n         * Called when a {@link Pipeline} element executes a {@link State}\n         * change.\n         *\n         * @param source the element which posted the message.\n         * @param old the old state that the element is changing from.\n         * @param current the new (current) state the element is changing to.\n         * @param pending the pending (target) state.\n         */\n        public void stateChanged(GstObject source, State old, State current, State pending);\n    }\n\n    /**\n     * Signal emitted when the pipeline is buffering data.\n     *\n     * @see #connect(BUFFERING)\n     * @see #disconnect(BUFFERING)\n     */\n    public static interface BUFFERING {\n\n        /**\n         * Called when a {@link Pipeline} element needs to buffer data before it\n         * can continue processing.\n         * <p>\n         * {@code percent} is a value between 0 and 100. A value of 100 means\n         * that the buffering completed.\n         * <p>\n         * When {@code percent} is less than 100 the application should PAUSE a\n         * PLAYING pipeline. When {@code percent} is 100, the application can\n         * set the pipeline (back) to PLAYING.\n         * <p>\n         * The application must be prepared to receive BUFFERING messages in the\n         * PREROLLING state and may only set the pipeline to PLAYING after\n         * receiving a message with {@code percent} set to 100, which can happen\n         * after the pipeline completed prerolling.\n         *\n         * @param source the element which posted the message.\n         * @param percent the percentage of buffering that has completed.\n         */\n        public void bufferingData(GstObject source, int percent);\n    }\n\n    /**\n     * Signal sent when a new duration message is posted by an element that know\n     * the duration of a stream in a specific format.\n     * <p>\n     * This message is received by bins and is used to calculate the total\n     * duration of a pipeline.\n     * <p>\n     * Elements may post a duration message with a duration of\n     * {@link ClockTime#NONE} to indicate that the duration has changed and the\n     * cached duration should be discarded. The new duration can then be\n     * retrieved via a query. The application can get the new duration with a\n     * duration query.\n     *\n     * @see #connect(DURATION)\n     * @see #disconnect(DURATION)\n     */\n    public static interface DURATION_CHANGED {\n\n        /**\n         * Called when a new duration message is posted on the Bus.\n         *\n         * @param source the element which posted the message.\n         */\n        public void durationChanged(GstObject source);\n    }\n\n    /**\n     * This message is posted by elements that start playback of a segment as a\n     * result of a segment seek.\n     * <p>\n     * This message is not received by the application but is used for\n     * maintenance reasons in container elements.\n     */\n    public static interface SEGMENT_START {\n\n        public void segmentStart(GstObject source, Format format, long position);\n    }\n\n    /**\n     * Signal emitted when the pipeline has completed playback of a segment.\n     * <p>\n     * This message is posted by elements that finish playback of a segment as a\n     * result of a segment seek. This message is received by the application\n     * after all elements that posted a {@link SEGMENT_START} have posted\n     * segment-done.\n     *\n     * @see #connect(SEGMENT_DONE)\n     * @see #disconnect(SEGMENT_DONE)\n     */\n    public static interface SEGMENT_DONE {\n\n        /**\n         * Called when a segment-done message has been posted.\n         *\n         * @param source the element which posted the message.\n         * @param format the format of the position being done.\n         * @param position the position of the segment being done.\n         */\n        public void segmentDone(GstObject source, Format format, long position);\n    }\n\n    /**\n     * Signal emitted by elements when they complete an ASYNC state change.\n     * <p>\n     * Applications will only receive this message from the top level pipeline.\n     * </p>\n     *\n     * @see #connect(ASYNC_DONE)\n     * @see #disconnect(ASYNC_DONE)\n     */\n    public static interface ASYNC_DONE {\n\n        /**\n         * Called when a segment-done message has been posted.\n         *\n         * @param source the element which posted the message.\n         */\n        public void asyncDone(GstObject source);\n    }\n\n    /**\n     * Catch all signals emitted on the Bus.\n     * <p>\n     * The signal handler will be called asynchronously from the thread that\n     * posted the message on the Bus.\n     *\n     * @see #connect(MESSAGE)\n     * @see #disconnect(MESSAGE)\n     */\n    public static interface MESSAGE {\n\n        /**\n         * Called when a {@link Element} posts a {@link Message} on the Bus.\n         *\n         * @param bus the Bus the message was posted on.\n         * @param message the message that was posted.\n         */\n        public void busMessage(Bus bus, Message message);\n    }\n\n    private static class MessageProxy<T> {\n\n        private final MessageType type;\n        private final Class<T> listenerClass;\n        private final Object listener;\n        private final BusCallback callback;\n\n        MessageProxy(MessageType type, Class<T> listenerClass, T listener, BusCallback callback) {\n            this.type = type;\n            this.listenerClass = listenerClass;\n            this.listener = listener;\n            this.callback = callback;\n        }\n\n        void busMessage(final GstBusPtr bus, final GstMessagePtr msg) {\n            if (type == MessageType.ANY || type.intValue() == msg.getMessageType()) {\n                callback.callback(bus, msg, null);\n            }\n        }\n    }\n\n    private static class SyncCallback implements GstBusAPI.BusSyncHandler {\n\n        {\n            Native.setCallbackThreadInitializer(this,\n                    new CallbackThreadInitializer(true,\n                            Boolean.getBoolean(\"glib.detachCallbackThreads\"),\n                            \"GstBus\"));\n        }\n\n        @Override\n        public BusSyncReply callback(final GstBusPtr busPtr, final GstMessagePtr msgPtr, Pointer userData) {\n            Bus bus = Natives.objectFor(busPtr, Bus.class, true, true);\n            // volatile - use local reference\n            BusSyncHandler syncHandler = bus.syncHandler;\n            if (syncHandler != null) {\n                Message msg = Natives.objectFor(msgPtr, Message.class, true, true);\n                BusSyncReply reply = syncHandler.syncMessage(msg);\n                if (reply != BusSyncReply.DROP) {\n                    Gst.getExecutor().execute(() -> bus.dispatchMessage(busPtr, msgPtr));\n                } else {\n                    // not calling dispatch message so unref here\n                    GSTMINIOBJECT_API.gst_mini_object_unref(msgPtr);\n                }\n            } else {\n                Gst.getExecutor().execute(() -> bus.dispatchMessage(busPtr, msgPtr));\n            }\n            return BusSyncReply.DROP;\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/BusSyncHandler.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.message.Message;\n\n/**\n * A BusSyncHandler will be invoked synchronously, when a new message has been\n * injected into a {@link Bus}. This function is mostly used internally. Only\n * one sync handler can be attached to a given bus.\n *\n * @see Bus#setSyncHandler(org.freedesktop.gstreamer.BusSyncHandler)\n */\npublic interface BusSyncHandler {\n\n    public BusSyncReply syncMessage(Message message);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/BusSyncReply.java",
    "content": "/* \n * Copyright (c) 2025 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.NativeEnum;\nimport org.freedesktop.gstreamer.message.Message;\n\n/**\n * The result values for a GstBusSyncHandler.\n */\npublic enum BusSyncReply implements NativeEnum<BusSyncReply> {\n    \n    /** Drop the {@link Message} */\n    DROP(0),\n    /** Pass the {@link Message} to the async queue */\n    PASS(1),\n    /** Pass {@link Message} to async queue, continue if message is handled */\n    ASYNC(2);\n    \n    private final int value;\n    \n    BusSyncReply(int value) {\n        this.value = value;\n    }\n    \n    /**\n     * Gets the integer value of the enum.\n     * @return The integer value for this enum.\n     */\n    @Override\n    public int intValue() {\n        return value;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/Caps.java",
    "content": "/*\n * Copyright (c) 2025 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (C) 2007 Wayne Meissner\n * Copyright (C) <2003> David A. Schleef <ds@schleef.org>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\n\nimport org.freedesktop.gstreamer.glib.Natives;\nimport static org.freedesktop.gstreamer.lowlevel.GstCapsAPI.GSTCAPS_API;\n\n/**\n * Structure describing sets of media formats\n * <p>\n * Caps (capabilities) are lightweight objects describing media types. They are\n * composed of an array of {@link Structure}.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstCaps.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstCaps.html</a>\n * <p>\n * Caps are exposed on {@link PadTemplate} to describe all possible types a\n * given pad can handle. They are also stored in the {@link Registry} along with\n * a description of the {@link Element}.\n * <p>\n * Caps are exposed on the element pads using the {@link Pad#getAllowedCaps() }\n * method. This method describes the possible types that the pad can handle or\n * produce at runtime.\n * <p>\n * Caps are also attached to buffers to describe the content of the data pointed\n * to by the buffer with {@link Sample#setCaps}. Caps attached to a\n * {@link Buffer} allow for format negotiation upstream and downstream.\n * <p>\n * A Caps can be constructed with the following code fragment:\n * <p>\n * <code>\n *  Caps caps = Caps.fromString(\"video/x-raw-rgb, bpp=32, depth=24, width=640, height=480\");\n * </code>\n * <p>\n * A Caps is fixed when it has no properties with ranges or lists. Use\n * {@link #isFixed} to test for fixed caps. Only fixed caps can be set on a\n * {@link Pad} or {@link Buffer}.\n * <p>\n * Various methods exist to work with the media types such as subtracting or\n * intersecting.\n *\n * @see Structure\n */\npublic class Caps extends MiniObject {\n\n    public static final String GTYPE_NAME = \"GstCaps\";\n\n    /**\n     * Creates a new Caps that is empty. That is, the returned Caps contains no\n     * media formats.\n     *\n     * @see #emptyCaps\n     */\n    public Caps() {\n        this(Natives.initializer(GSTCAPS_API.ptr_gst_caps_new_empty()));\n    }\n\n    /**\n     * Construct a new Caps from a string representation.\n     *\n     * @param caps The string representation of the caps.\n     * @see #fromString\n     */\n    public Caps(String caps) {\n        this(Natives.initializer(GSTCAPS_API.ptr_gst_caps_from_string(caps)));\n    }\n\n    /**\n     * Create a caps that is a copy of another caps.\n     *\n     * @param caps The caps to copy.\n     * @see #copy\n     */\n    public Caps(Caps caps) {\n        this(Natives.initializer(GSTCAPS_API.ptr_gst_caps_copy(caps)));\n    }\n\n    Caps(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Append the structures contained in caps to this caps object. The\n     * structures in caps are not copied -- they are transferred to this caps.\n     * <p>\n     * If either caps is ANY, the resulting caps will be ANY.\n     *\n     * @param caps The Caps to append\n     */\n    public void append(Caps caps) {\n        GSTCAPS_API.gst_caps_append(this, caps);\n    }\n\n    /**\n     * Append structure to this caps. The structure is not copied; this caps\n     * takes ownership, so do not use struct after calling this method.\n     *\n     * @param struct The structure to append.\n     */\n    public void append(Structure struct) {\n        GSTCAPS_API.gst_caps_append_structure(this, struct);\n    }\n\n    /**\n     * Create a new Caps as a copy of the this caps.\n     *\n     * The new Caps will be a copy of this caps, with all the internal\n     * structures copied as well.\n     *\n     * @return The new Caps.\n     */\n    public Caps copy() {\n        return GSTCAPS_API.gst_caps_copy(this);\n    }\n\n    @Override\n    public boolean equals(Object other) {\n        if (other == null || !(other instanceof Caps)) {\n            return false;\n        }\n        return other == this || isEqual((Caps) other);\n    }\n\n    /**\n     * Get a {@link Structure} contained in this caps.\n     *\n     * Finds the structure in @caps that has the index @index, and returns it.\n     *\n     * @param index The index of the structure to get.\n     * @return The Structure corresponding to index.\n     */\n    public Structure getStructure(int index) {\n        /*\n         * WARNING: This function takes a const GstCaps *, but returns a\n         * non-const GstStructure *.  This is for programming convenience --\n         * the caller should be aware that structures inside a constant\n         * #GstCaps should not be modified.\n         */\n        // The above means we return a Structure proxy which does not own the pointer.\n        // gst_caps_get_structure is not marked as CallerOwnsReturn, so it should work\n        return GSTCAPS_API.gst_caps_get_structure(this, index);\n    }\n\n    /**\n     * Creates a new {@link Caps} that contains all the formats that are common\n     * to both this Caps and the other Caps.\n     *\n     * @param other The {@link Caps} to intersect with this one.\n     *\n     * @return The new {@link Caps}\n     */\n    public Caps intersect(Caps other) {\n        return GSTCAPS_API.gst_caps_intersect(this, other);\n    }\n\n    /**\n     * Check if this caps is always compatible with another caps.\n     * <p>\n     * A given Caps structure is always compatible with another if every media\n     * format that is in the first is also contained in the second. That is,\n     * this caps1 is a subset of other.\n     *\n     * @param other The caps to test against.\n     * @return true if other is always compatible with this caps.\n     */\n    public boolean isAlwaysCompatible(Caps other) {\n        return GSTCAPS_API.gst_caps_is_always_compatible(this, other);\n    }\n\n    /**\n     * Determine if this caps represents any media format.\n     *\n     * @return true if this caps represents any format.\n     */\n    public boolean isAny() {\n        return GSTCAPS_API.gst_caps_is_any(this);\n    }\n\n    /**\n     * Determine if this caps represents no media formats.\n     *\n     * @return true if this caps represents no formats.\n     */\n    public boolean isEmpty() {\n        return GSTCAPS_API.gst_caps_is_empty(this);\n    }\n\n    /**\n     * Checks if the given caps represent the same set of caps.\n     * <p>\n     * This function does not work reliably if optional properties for caps are\n     * included on one caps and omitted on the other.\n     *\n     * @param other The caps to compare this caps to.\n     * @return true if other caps equals this one.\n     */\n    public boolean isEqual(Caps other) {\n        return GSTCAPS_API.gst_caps_is_equal(this, other);\n    }\n\n    /**\n     * Tests if two Caps are equal. This function only works on fixed Caps.\n     *\n     * @param other The other caps to test against.\n     * @return true if the other caps is equal to this one.\n     */\n    public boolean isEqualFixed(Caps other) {\n        return GSTCAPS_API.gst_caps_is_equal_fixed(this, other);\n    }\n\n    /**\n     * Determine if this caps is fixed.\n     * <p>\n     * Fixed Caps describe exactly one format, that is, they have exactly one\n     * structure, and each field in the structure describes a fixed type.\n     * Examples of non-fixed types are GST_TYPE_INT_RANGE and GST_TYPE_LIST.\n     *\n     * @return true if this caps is fixed\n     */\n    public boolean isFixed() {\n        return GSTCAPS_API.gst_caps_is_fixed(this);\n    }\n\n    /**\n     * Checks if all caps represented by this caps are also represented by\n     * superset.\n     * <p>\n     * This function does not work reliably if optional properties for caps are\n     * included on one caps and omitted on the other.\n     *\n     * @param superset The potentially greater Caps\n     * @return true if this caps is a subset of superset\n     */\n    public boolean isSubset(Caps superset) {\n        return GSTCAPS_API.gst_caps_is_subset(this, superset);\n    }\n\n    /**\n     *\n     * Returns a writable copy of this caps.\n     * <p>\n     * This method will invalidate the native side of this caps object, so it\n     * should not be used after calling this method, and only the returned Caps\n     * object should be used.\n     * <p>\n     *\n     * @return A writable version of this caps object.\n     */\n    // @TODO should this take a ref ?\n    public Caps makeWritable() {\n        return GSTCAPS_API.gst_caps_make_writable(this);\n    }\n\n    /**\n     * Normalize the Caps.\n     *\n     * Creates a new {@link Caps} that represents the same set of formats as\n     * this Caps, but contains no lists. Each list is expanded into separate\n     * {@link Structure}s\n     *\n     * @return The new {@link Caps}\n     * @see Structure\n     */\n    public Caps normalize() {\n//        this.ref(); // gst_caps_normalize copies \"this\" and drops one reference\n        Natives.ref(this);\n        return GSTCAPS_API.gst_caps_normalize(this);\n    }\n\n    /**\n     * Remove a structure from the caps. Removes the structure with the given\n     * index from the list of structures contained in this caps.\n     *\n     * @param index Index of the structure to remove.\n     */\n    public void removeStructure(int index) {\n        GSTCAPS_API.gst_caps_remove_structure(this, index);\n    }\n\n    public void setInteger(String field, Integer value) {\n        GSTCAPS_API.gst_caps_set_simple(this, field, value, null);\n    }\n\n    /**\n     * Modifies this caps inplace into a representation that represents the same\n     * set of formats, but in a simpler form. Component structures that are\n     * identical are merged. Component structures that have values that can be\n     * merged are also merged.\n     *\n     * @return The new {@link Caps}\n     */\n    public Caps simplify() {\n//        this.ref(); // gst_caps_simplify copies \"this\" and drops one reference\n        Natives.ref(this);\n        return GSTCAPS_API.gst_caps_simplify(this);\n    }\n\n    /**\n     * Get the number of structures contained in this caps.\n     *\n     * @return the number of structures that this caps contains\n     */\n    public int size() {\n        return GSTCAPS_API.gst_caps_get_size(this);\n    }\n\n    /**\n     * Subtracts the subtrahend Caps from this Caps.\n     *\n     * <note>This function does not work reliably if optional properties for\n     * caps are included on one caps and omitted on the other.</note>\n     *\n     * @param subtrahend The {@link Caps} to subtract.\n     * @return The resulting caps.\n     */\n    public Caps subtract(Caps subtrahend) {\n        return GSTCAPS_API.gst_caps_subtract(this, subtrahend);\n    }\n\n    @Override\n    public String toString() {\n        return GSTCAPS_API.gst_caps_to_string(this);\n    }\n\n    /**\n     * Destructively discard all but the first structure from this caps.\n     *\n     * Useful when fixating. This caps must be writable.\n     *\n     * @return truncated copy of the Caps\n     */\n    public Caps truncate() {\n//        this.ref();\n        Natives.ref(this);\n        return GSTCAPS_API.gst_caps_truncate(this);\n    }\n\n    /**\n     * Creates a new Caps that indicates that it is compatible with any media\n     * format.\n     *\n     * @return The new Caps.\n     */\n    public static Caps anyCaps() {\n        return new Caps(Natives.initializer(GSTCAPS_API.ptr_gst_caps_new_any()));\n    }\n\n    /**\n     * Creates a new Caps that is empty. That is, the returned Caps contains no\n     * media formats.\n     *\n     * @return The new Caps.\n     */\n    public static Caps emptyCaps() {\n        return new Caps(Natives.initializer(GSTCAPS_API.ptr_gst_caps_new_empty()));\n    }\n\n    /**\n     * Construct a new Caps from a string representation. Example:\n     * <p>\n     * <code>\n     *  Caps caps = Caps.fromString(\"video/x-raw, format=RGB, bpp=32, depth=24, width=640, height=480\");\n     * </code>\n     *\n     * @param caps The string representation of the caps.\n     * @return The new Caps.\n     */\n    public static Caps fromString(String caps) {\n        return new Caps(Natives.initializer(GSTCAPS_API.ptr_gst_caps_from_string(caps)));\n    }\n\n    /**\n     * Merge two {@link Caps} together.\n     * <p>\n     * Appends the structures contained in caps2 to caps1 if they are not yet\n     * expressed by caps1 . The structures in caps2 are not copied -- they are\n     * transferred to a writable copy of caps1 , and then caps2 is freed. If\n     * either caps is ANY, the resulting caps will be ANY.\n     * </p>\n     *\n     * @param caps1 the {@link Caps} that will take the new entries.\n     * @param caps2 the {@link Caps} to merge in\n     * @return merged Caps\n     */\n    public static Caps merge(Caps caps1, Caps caps2) {\n        return GSTCAPS_API.gst_caps_merge(caps1, caps2);\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/Clock.java",
    "content": "/* \n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wtay@chello.be>\n *                    2004 Wim Taymans <wim@fluendo.com>\n * \n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstClockAPI.GSTCLOCK_API;\n\n/**\n * Abstract class for global clocks.\n * <p>\n * GStreamer uses a global clock to synchronize the plugins in a pipeline.\n * Different clock implementations are possible by implementing this abstract\n * base class.\n * <p>\n * The {@link Clock} returns a monotonically increasing time with the method\n * gst_clock_get_time(). Its accuracy and base time depend on the specific\n * clock implementation but time is always expressed in nanoseconds. Since the\n * baseline of the clock is undefined, the clock time returned is not\n * meaningful in itself, what matters are the deltas between two clock times.\n * The time returned by a clock is called the absolute time.\n * <p>\n * The pipeline uses the clock to calculate the stream time. Usually all\n * renderers synchronize to the global clock using the buffer timestamps, the\n * newsegment events and the element's base time, see #GstPipeline.\n * <p>\n * A clock implementation can support periodic and single shot clock\n * notifications both synchronous and asynchronous.\n * <p>\n * One first needs to create a {@link ClockID} for the periodic or single shot\n * notification using {@link #newSingleShotID} or {@link #newPeriodicID}.\n * <p>\n * To perform a blocking wait for the specific time of the {@link ClockID} use the\n * gst_clock_id_wait(). To receive a callback when the specific time is reached\n * in the clock use gst_clock_id_wait_async(). Both these calls can be\n * interrupted with the gst_clock_id_unschedule() call. If the blocking wait is\n * unscheduled a return value of GST_CLOCK_UNSCHEDULED is returned.\n * <p>\n * Periodic callbacks scheduled async will be repeatedly called automatically\n * until it is unscheduled. To schedule a sync periodic callback,\n * gst_clock_id_wait() should be called repeatedly.\n * <p>\n * The async callbacks can happen from any thread, either provided by the core\n * or from a streaming thread. The application should be prepared for this.\n * <p>\n * A {@link ClockID} that has been unscheduled cannot be used again for any wait\n * operation, a new ClockID should be created.\n * <p>\n * It is possible to perform a blocking wait on the same ClockID from\n * multiple threads. However, registering the same ClockID for multiple\n * async notifications is not possible, the callback will only be called for\n * the thread registering the entry last.\n * <p>\n * These clock operations do not operate on the stream time, so the callbacks\n * will also occur when not in {@link State#PLAYING} state as if the clock just keeps on\n * running. Some clocks however do not progress when the element that provided\n * the clock is not {@link State#PLAYING}.\n * <p>\n * When a clock has the GST_CLOCK_FLAG_CAN_SET_MASTER flag set, it can be\n * slaved to another #GstClock with the gst_clock_set_master(). The clock will\n * then automatically be synchronized to this master clock by repeatedly\n * sampling the master clock and the slave clock and recalibrating the slave\n * clock with {@link #setCalibration}. This feature is mostly useful for\n * plugins that have an internal clock but must operate with another clock\n * selected by the {@link Pipeline}.  They can track the offset and rate difference\n * of their internal clock relative to the master clock by using the\n * gst_clock_get_calibration() function. \n * <p>\n * The master/slave synchronisation can be tuned with the \"timeout\", \"window-size\"\n * and \"window-threshold\" properties. The \"timeout\" property defines the interval\n * to sample the master clock and run the calibration functions. \n * \"window-size\" defines the number of samples to use when calibrating and\n * \"window-threshold\" defines the minimum number of samples before the \n * calibration is performed.\n */\npublic class Clock extends GstObject {\n    public static final String GTYPE_NAME = \"GstClock\";\n\n    @Deprecated // should be package private\n    public Clock(Initializer init) {\n        super(init); \n    }\n    \n    /**\n     * Sets the accuracy of the clock. \n     * <p>\n     * Some clocks have the possibility to operate with different accuracy at \n     * the expense of more resource usage. There is normally no need to change \n     * the default resolution of a clock. The resolution of a clock can only be \n     * changed if the clock has the GST_CLOCK_FLAG_CAN_SET_RESOLUTION flag set.\n     *\n     * @param resolution the new resolution of the clock.\n     * @return the new resolution of the clock.\n     */\n    public long setResolution(long resolution) {\n        return GSTCLOCK_API.gst_clock_set_resolution(this, resolution);\n    }\n    \n    /**\n     * Gets the accuracy of the clock. The accuracy of the clock is the granularity\n     * of the values returned by {@link #getTime}.\n     *\n     * @return the resolution of the clock in nanoseconds.\n     */\n    public long getResolution() {\n        return GSTCLOCK_API.gst_clock_get_resolution(this);\n    }\n    \n    /**\n     * Gets the current time of the given clock. The time is always\n     * monotonically increasing and adjusted according to the current\n     * offset and rate.\n     *\n     * Returns: the time of the clock. Or GST_CLOCK_TIME_NONE when\n     * giving wrong input.\n     * @return the time of the clock. Or {@link ClockTime#NONE} when\n     * given incorrect input.\n     */\n    public long getTime() {\n        return GSTCLOCK_API.gst_clock_get_time(this);\n    }\n    /**\n     * Gets the current internal time of this clock. The time is returned\n     * unadjusted for the offset and the rate.\n     *\n     * Thread safe.\n     * \n     * @return the internal time of the clock. Or {@link ClockTime#NONE} when given wrong input.\n     */\n    public long getInternalTime() {\n        return GSTCLOCK_API.gst_clock_get_internal_time(this);\n    }\n    \n    /**\n     * Gets the master clock that this clock is slaved to or null when the clock is\n     * not slaved to any master clock.\n     *\n     * @return A master Clock or null when this clock is not slaved to a master\n     * clock.\n     */\n    public Clock getMaster() {\n        return GSTCLOCK_API.gst_clock_get_master(this);\n    }\n    \n    /**\n     * Set master as the master clock for this clock. This clock will be automatically\n     * calibrated so that {@link #getTime} reports the same time as the\n     * master clock.  \n     * \n     * A clock provider that slaves its clock to a master can get the current\n     * calibration values with {@link #getCalibration}.\n     *\n     * master can be null in which case clock will not be slaved anymore. It will\n     * however keep reporting its time adjusted with the last configured rate \n     * and time offsets.\n     *\n     * @param master a master Clock \n     * @return true if the clock is capable of being slaved to a master clock. \n     * Trying to set a master on a clock without the CAN_SET_MASTER flag will make \n     * this function return false.\n     */\n    public boolean setMaster(Clock master) {\n        return GSTCLOCK_API.gst_clock_set_master(this, master);\n    }\n    \n    /**\n     * Gets the internal rate and reference time of clock. See {@link #setCalibration} for more information.\n     * <p>\n     * internal, external, rate_num, and rate_denom can be left NULL if the caller is not interested in the values.\n     *\n     * Thread safe.\n     * @param internal a reference internal time\n     * @param external a reference external time\n     * @param rateNumerator the numerator of the rate of the clock relative to its internal time\n     * @param rateDenominator the denominator of the rate of the clock\n     */\n    @Deprecated\n    public void getCalibration(long internal, long external, long rateNumerator, long rateDenominator) {\n        GSTCLOCK_API.gst_clock_set_calibration(this, internal, external, rateNumerator, rateDenominator);\n    }\n    \n    /**\n     * Gets the internal rate and reference time of clock. See\n     * {@link #setCalibration} for more information.\n     *\n     * @return calibration\n     */\n    public Calibration getCalibration() {\n        long[] internalPtr = new long[1];\n        long[] externalPtr = new long[1];\n        long[] rateNumPtr = new long[1];\n        long[] rateDenomPtr = new long[1];\n        GSTCLOCK_API.gst_clock_get_calibration(this, internalPtr,\n                externalPtr, rateNumPtr, rateDenomPtr);\n        return new Calibration(internalPtr[0], externalPtr[0],\n                rateNumPtr[0], rateDenomPtr[0]);\n    }\n    \n    /**\n     *  Adjusts the rate and time of this clock. A rate of 1/1 is the normal speed of\n     * the clock. Values bigger than 1/1 make the clock go faster.\n     * <p>\n     * internal and external are calibration parameters that arrange that\n     * {@link #getTime} should have been external at internal time internal.\n     * This internal time should not be in the future; that is, it should be less\n     * than the value of {@link #getInternalTime} when this function is called.\n     * <p>\n     * Subsequent calls to gst_clock_get_time() will return clock times computed as\n     * follows:\n     * <p>\n     * <code>\n     *   time = (internal_time - internal) * rateNumerator/ rateDenominator + external\n     * </code>\n     * <p>\n     * This formula is implemented in gst_clock_adjust_unlocked(). Of course, it\n     * tries to do the integer arithmetic as precisely as possible.\n     * <p>\n     * Note that {@link #getTime} always returns increasing values so when you\n     * move the clock backwards, getTime() will report the previous value\n     * until the clock catches up.\n     *\n     * Thread safe.\n     * @param internal a reference internal time\n     * @param external a reference external time\n     * @param rateNumerator the numerator of the rate of the clock relative to its internal time\n     * @param rateDenominator the denominator of the rate of the clock\n     */\n    public void setCalibration(long internal, long external, long rateNumerator, long rateDenominator) {\n        GSTCLOCK_API.gst_clock_set_calibration(this, internal, external, rateNumerator, rateDenominator);\n    }\n    \n    /**\n     * Gets a {@link ClockID} from this clock to trigger a single shot\n     * notification at the requested time.\n     * <p>\n     * Thread safe.\n     * \n     * @param time The requested time\n     * @return A {@link ClockID} that can be used to request the time notification.\n     */\n    public ClockID newSingleShotID(long time) {\n        return GSTCLOCK_API.gst_clock_new_single_shot_id(this, time);\n    }\n    \n    /**\n     * Gets an ID from this clock to trigger a periodic notification.\n     * The periodeic notifications will be start at time start_time and\n     * will then be fired with the given interval.\n     * <p>\n     * Thread safe.\n     * \n     * @param startTime The requested start time.\n     * @param interval The requested interval.\n     * @return A {@link ClockID} that can be used to request the time notification.\n     */\n    public ClockID newPeriodicID(long startTime, long interval) {\n        return GSTCLOCK_API.gst_clock_new_periodic_id(this, startTime, interval);\n    }\n    \n    /**\n     * Data storage for clock calibration.\n     */\n    public static final class Calibration {\n        \n        private final long internal;\n        private final long external;\n        private final long rateNum;\n        private final long rateDenom;\n\n        private Calibration(long internal, long external, long rateNum, long rateDenom) {\n            this.internal = internal;\n            this.external = external;\n            this.rateNum = rateNum;\n            this.rateDenom = rateDenom;\n        }\n\n        /**\n         * The internal time.\n         * \n         * @return internal time\n         */\n        public long internal() {\n            return internal;\n        }\n\n        /**\n         * The external time.\n         * \n         * @return external time\n         */\n        public long external() {\n            return external;\n        }\n\n        /**\n         * The rate numerator.\n         * \n         * @return rate numerator\n         */\n        public long rateNum() {\n            return rateNum;\n        }\n\n        /**\n         * The rate denominator.\n         * \n         * @return rate denominator\n         */\n        public long rateDenom() {\n            return rateDenom;\n        }\n\n        @Override\n        public int hashCode() {\n            int hash = 7;\n            hash = 59 * hash + (int) (this.internal ^ (this.internal >>> 32));\n            hash = 59 * hash + (int) (this.external ^ (this.external >>> 32));\n            hash = 59 * hash + (int) (this.rateNum ^ (this.rateNum >>> 32));\n            hash = 59 * hash + (int) (this.rateDenom ^ (this.rateDenom >>> 32));\n            return hash;\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (this == obj) {\n                return true;\n            }\n            if (obj == null) {\n                return false;\n            }\n            if (getClass() != obj.getClass()) {\n                return false;\n            }\n            final Calibration other = (Calibration) obj;\n            if (this.internal != other.internal) {\n                return false;\n            }\n            if (this.external != other.external) {\n                return false;\n            }\n            if (this.rateNum != other.rateNum) {\n                return false;\n            }\n            if (this.rateDenom != other.rateDenom) {\n                return false;\n            }\n            return true;\n        }\n\n        @Override\n        public String toString() {\n            return \"Calibration{\" + \"internal=\" + internal + \", external=\" + external\n                    + \", rateNum=\" + rateNum + \", rateDenom=\" + rateDenom + '}';\n        }\n        \n        \n    }\n    \n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/ClockID.java",
    "content": "/* \n * Copyright (c) 2025 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.RefCountedObject;\nimport org.freedesktop.gstreamer.lowlevel.GPointer;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstClockAPI.GSTCLOCK_API;\n\n/**\n * A datatype to hold the handle to an outstanding sync or async clock callback.\n */\npublic class ClockID extends RefCountedObject implements Comparable<ClockID> {\n\n    ClockID(Initializer init) {\n        super(new Handle(init.ptr, init.ownsHandle), init.needRef);\n    }\n\n    /**\n     * Cancel an outstanding request. This can either be an outstanding async\n     * notification or a pending sync notification. After this call, @id cannot\n     * be used anymore to receive sync or async notifications, you need to\n     * create a new #GstClockID.\n     */\n    public void unschedule() {\n        GSTCLOCK_API.gst_clock_id_unschedule(this);\n    }\n\n    /**\n     * Gets the time of the clock ID\n     * <p>\n     * Thread safe.\n     *\n     * @return The time of this clock id.\n     */\n    public long getTime() {\n        return GSTCLOCK_API.gst_clock_id_get_time(this);\n    }\n\n    /**\n     * Compares this ClockID to another.\n     *\n     * @param other The other ClockID to compare to\n     * @return negative value if\n     * {@code a < b; zero if a = b; positive value if a > b}\n     */\n    @Override\n    public int compareTo(ClockID other) {\n        return GSTCLOCK_API.gst_clock_id_compare_func(this, other);\n    }\n\n    private static final class Handle extends RefCountedObject.Handle {\n\n        public Handle(GPointer ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n\n        @Override\n        protected void disposeNativeHandle(GPointer ptr) {\n            GSTCLOCK_API.gst_clock_id_unref(ptr);\n        }\n\n        @Override\n        protected void ref() {\n            GSTCLOCK_API.gst_clock_id_ref(getPointer());\n        }\n\n        @Override\n        protected void unref() {\n            GSTCLOCK_API.gst_clock_id_unref(getPointer());\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/ClockReturn.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wtay@chello.be>\n *                    2005 Wim Taymans <wim@fluendo.com>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue;\n\n/**\n * The return value of a clock operation.\n */\npublic enum ClockReturn {\n    /** The operation succeeded. */\n    OK,\n    /** The operation was scheduled too late. */\n    EARLY,\n    /** The clockID was unscheduled */\n    UNSCHEDULED,\n    /** The ClockID is busy */\n    BUSY,\n    /** A bad time was provided to a function. */\n    BADTIME,\n    /** An error occured */\n    ERROR,\n    /** Operation is not supported */\n    @DefaultEnumValue\n    UNSUPPORTED,\n    /** The ClockID is done waiting */\n    DONE\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/ClockTime.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport java.util.concurrent.TimeUnit;\n\n/**\n * Utility methods for working with clock time (ns) in GStreamer.\n */\npublic final class ClockTime {\n\n    public final static long NONE = -1;\n    public final static long ZERO = 0;\n\n    \n    private ClockTime() {}\n    \n    /**\n     * Convert time in microseconds to GStreamer clocktime (nanoseconds)\n     *\n     * @param microseconds the microsecond value to represent.\n     * @return time in nanoseconds\n     */\n    public static long fromMicros(long microseconds) {\n        return TimeUnit.MICROSECONDS.toNanos(microseconds);\n    }\n\n    /**\n     * Convert GStreamer clocktime (nanoseconds) to microseconds.\n     *\n     * @param clocktime nanosecond time\n     * @return time in microseconds\n     */\n    public static long toMicros(long clocktime) {\n        return TimeUnit.NANOSECONDS.toMicros(clocktime);\n    }\n    \n    /**\n     * Convert time in milliseconds to GStreamer clocktime (nanoseconds)\n     *\n     * @param milliseconds the millisecond value to represent.\n     * @return time in nanoseconds\n     */\n    public static long fromMillis(long milliseconds) {\n        return TimeUnit.MILLISECONDS.toNanos(milliseconds);\n    }\n\n    /**\n     * Convert GStreamer clocktime (nanoseconds) to milliseconds.\n     *\n     * @param clocktime nanosecond time\n     * @return time in milliseconds\n     */\n    public static long toMillis(long clocktime) {\n        return TimeUnit.NANOSECONDS.toMillis(clocktime);\n    }\n\n    /**\n     * Convert time in milliseconds to GStreamer clocktime (nanoseconds)\n     *\n     * @param seconds the seconds value to represent.\n     * @return time in nanoseconds\n     */\n    public static long fromSeconds(long seconds) {\n        return TimeUnit.SECONDS.toNanos(seconds);\n    }\n\n    /**\n     * Convert GStreamer clocktime (nanoseconds) to seconds.\n     *\n     * @param clocktime nanosecond time\n     * @return time in milliseconds\n     */\n    public static long toSeconds(long clocktime) {\n        return TimeUnit.NANOSECONDS.toSeconds(clocktime);\n    }\n\n    /**\n     * Get the hours component of the total time.\n     *\n     * @param clocktime GStreamer time in nanoseconds\n     * @return The hours component of the total time.\n     */\n    public static long getHoursComponent(long clocktime) {\n        return (toSeconds(clocktime) / 3600) % 24;\n    }\n\n    /**\n     * Get the minutes component of the total time.\n     *\n     * @param clocktime GStreamer time in nanoseconds\n     * @return The minutes component of the total time.\n     */\n    public static long getMinutesComponent(long clocktime) {\n        return (toSeconds(clocktime) / 60) % 60;\n    }\n\n    /**\n     * Get the seconds component of the total time.\n     *\n     * @param clocktime GStreamer time in nanoseconds\n     * @return The seconds component of the total time.\n     */\n    public static long getSecondsComponent(long clocktime) {\n        return toSeconds(clocktime) % 60;\n    }\n\n    /**\n     * Determines if this ClockTime represents a valid time value.\n     *\n     * @param clocktime GStreamer time in nanoseconds\n     * @return true if valid, else false\n     */\n    public static boolean isValid(long clocktime) {\n        return clocktime != NONE;\n    }\n\n    /**\n     * Returns a {@code String} representation of this {@code ClockTime}.\n     *\n     * @param clocktime GStreamer time in nanoseconds\n     * @return a string representation of this {@code ClockTime}\n     */\n    public static String toString(long clocktime) {\n        return String.format(\"%02d:%02d:%02d\",\n                getHoursComponent(clocktime),\n                getMinutesComponent(clocktime),\n                getSecondsComponent(clocktime));\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/Context.java",
    "content": "/*\n * Copyright (c) 2025 Neil C Smith\n * Copyright (c) 2019 Christophe Lafolet\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.lowlevel.GstContextAPI;\nimport org.freedesktop.gstreamer.lowlevel.GstContextPtr;\n\n/**\n * Lightweight objects to represent element contexts.\n * <p>\n * See upstream documentation at <a href=\n * \"https://gstreamer.freedesktop.org/documentation/gstreamer/gstcontext.html\"\n * >https://gstreamer.freedesktop.org/documentation/gstreamer/gstcontext.html</a>\n * <p>\n * Context is a container object used to store contexts like a device context, a\n * display server connection and similar concepts that should be shared between\n * multiple elements.\n * <p>\n * Applications can set a context on a complete pipeline by using\n * {@link Element#setContext(Context)}, which will then be propagated to all\n * child elements. Elements can handle these in\n * {@link Element#setContext(Context)} and merge them with the context\n * information they already have.\n * <p>\n * When an element needs a context it will do the following actions in this\n * order until one step succeeds:\n * <ol>\n * <li>Check if the element already has a context</li>\n * <li>Query downstream with GST_QUERY_CONTEXT for the context</li>\n * <li>Query upstream* with GST_QUERY_CONTEXT for the context</li>\n * <li>Post a GST_MESSAGE_NEED_CONTEXT message on the bus with the required\n * context types and afterwards check if a usable context was set now</li>\n * <li>Create a context by itself and post a GST_MESSAGE_HAVE_CONTEXT message on\n * the bus.</li>\n * </ol>\n * <p>\n * Bins will catch GST_MESSAGE_NEED_CONTEXT messages and will set any previously\n * known context on the element that asks for it if possible. Otherwise the\n * application should provide one if it can.\n * <p>\n * Contexts can be persistent. A persistent context is kept in elements when\n * they reach {@link State#NULL}, non-persistent ones will be removed. Also, a\n * non-persistent context won't override a previous persistent context set to an\n * element.\n */\npublic class Context extends MiniObject {\n\n    public static final String GTYPE_NAME = \"GstContext\";\n\n    private final Handle handle;\n\n    public Context(String contextType) {\n        this(contextType, true);\n    }\n\n    /**\n     * Create a new context.\n     */\n    public Context(String context_type, boolean persistent) {\n        this(new Handle(GstContextAPI.GSTCONTEXT_API.gst_context_new(context_type, persistent), true), false);\n    }\n\n    Context(Handle handle, boolean needRef) {\n        super(handle, needRef);\n        this.handle = handle;\n    }\n\n    Context(Initializer init) {\n        this(new Handle(init.ptr.as(GstContextPtr.class, GstContextPtr::new), init.ownsHandle), init.needRef);\n    }\n\n    /**\n     * Access the structure of the context.\n     *\n     * @return The structure of this context. The structure is still owned by this\n     *         context, which means that you should not modify it and not dispose of\n     *         it.\n     */\n    public Structure getStructure() {\n        return GstContextAPI.GSTCONTEXT_API.gst_context_get_structure(handle.getPointer());\n    }\n\n    /**\n     * Get a writable version of the structure.\n     *\n     * @return The structure of this context. The structure is still owned by the\n     *         context, which means that you should not dispose of it.\n     */\n    public Structure getWritableStructure() {\n        return GstContextAPI.GSTCONTEXT_API.gst_context_writable_structure(handle.getPointer());\n    }\n\n    /**\n     * Get the type of this context.\n     *\n     * @return The type of this context.\n     */\n    public String getContextType() {\n        return GstContextAPI.GSTCONTEXT_API.gst_context_get_context_type(handle.getPointer());\n    }\n\n    protected static class Handle extends MiniObject.Handle {\n\n        public Handle(GstContextPtr ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n\n        @Override\n        protected GstContextPtr getPointer() {\n            return (GstContextPtr) super.getPointer();\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/ControlBinding.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.lowlevel.GValueAPI;\nimport org.freedesktop.gstreamer.lowlevel.GstControlBindingPtr;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstControlBindingAPI.GSTCONTROLBINDING_API;\n\n/**\n * Attachment for control source sources.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstControlBinding.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstControlBinding.html</a>\n * <p>\n */\npublic class ControlBinding extends GstObject {\n\n    public static final String GTYPE_NAME = \"GstControlBinding\";\n    \n    private final Handle handle;\n\n    protected ControlBinding(Handle handle, boolean needRef) {\n        super(handle, needRef);\n        this.handle = handle;\n    }\n\n    ControlBinding(Initializer init) {\n        this(new Handle(\n                init.ptr.as(GstControlBindingPtr.class, GstControlBindingPtr::new),\n                init.ownsHandle),\n                init.needRef);\n    }\n\n    /**\n     * Gets the value for the given controlled property at the requested time.\n     *\n     * @param timestamp the time the control-change should be read from\n     * @return the value of the property at the given time, or NULL if the\n     * property isn't controlled\n     */\n    public Object getValue(long timestamp) {\n        GValueAPI.GValue gValue = GSTCONTROLBINDING_API.gst_control_binding_get_value(\n                handle.getPointer(), timestamp);\n        return gValue == null ? null : gValue.getValue();\n    }\n\n    /**\n     * Gets a number of values for the given controlled property starting at\n     * the requested time.\n     * <p>\n     * This function is useful if one wants to e.g. draw a graph of the control\n     * curve or apply a control curve sample by sample.\n     * \n     * @param timestamp the time that should be processed\n     * @param interval the time spacing between subsequent values\n     * @param values array to fill with control values\n     * @return false if the given array could not be filled\n     */\n    public boolean getValueArray(long timestamp, long interval, Object[] values) {\n        GValueAPI.GValue[] gValues = new GValueAPI.GValue[values.length];\n        boolean ok = GSTCONTROLBINDING_API.gst_control_binding_get_g_value_array(\n                handle.getPointer(),\n                timestamp,\n                interval,\n                gValues.length,\n                gValues);\n        if (ok) {\n            for (int i = 0; i < values.length; i++) {\n                values[i] = gValues[i].getValue();\n            }\n        }\n        return ok;\n    }\n    \n    /**\n     * This function is used to disable a control binding for some time, i.e.\n     * GstObject.syncValues() will do nothing.\n     * \n     * @param disabled whether to disable the controller or not\n     */\n    public void setDisabled(boolean disabled) {\n        GSTCONTROLBINDING_API.gst_control_binding_set_disabled(handle.getPointer(), disabled);\n    }\n    \n    /**\n     * Check if the control binding is disabled.\n     * \n     * @return TRUE if the binding is inactive\n     */\n    public boolean isDisabled() {\n        return GSTCONTROLBINDING_API.gst_control_binding_is_disabled(handle.getPointer());\n        \n    }\n    \n\n    protected static class Handle extends GstObject.Handle {\n\n        public Handle(GstControlBindingPtr ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n\n        @Override\n        protected GstControlBindingPtr getPointer() {\n            return (GstControlBindingPtr) super.getPointer();\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/ControlSource.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.lowlevel.GstControlSourcePtr;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstControlSourceAPI.GSTCONTROLSOURCE_API;\n\n/**\n * Base class for control source sources.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstControlSource.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstControlSource.html</a>\n * <p>\n */\npublic class ControlSource extends GstObject {\n    \n    public static final String GTYPE_NAME = \"GstControlSource\";\n\n    private final Handle handle;\n\n    protected ControlSource(Handle handle, boolean needRef) {\n        super(handle, needRef);\n        this.handle = handle;\n    }\n\n    ControlSource(Initializer init) {\n        this(new Handle(\n                init.ptr.as(GstControlSourcePtr.class, GstControlSourcePtr::new),\n                init.ownsHandle),\n                init.needRef);\n    }\n\n    /**\n     * Gets the value for this ControlSource at a given timestamp.\n     *\n     * @param timestamp the time for which the value should be returned\n     * @return value\n     * @throws IllegalStateException if the value could not be calculated\n     */\n    public double getValue(long timestamp) {\n        double[] out = new double[1];\n        boolean ok = GSTCONTROLSOURCE_API.gst_control_source_get_value(handle.getPointer(), timestamp, out);\n        if (ok) {\n            return out[0];\n        } else {\n            throw new IllegalStateException();\n        }\n    }\n\n    /**\n     * Gets an array of values for for this ControlSource. Values that are\n     * undefined contain NANs.\n     *\n     * @param timestamp the first timestamp\n     * @param interval the time steps\n     * @param values array to put control-values in\n     * @return true if the values were successfully calculated\n     */\n    public boolean getValueArray(long timestamp, long interval, double[] values) {\n        return GSTCONTROLSOURCE_API.gst_control_source_get_value_array(\n                handle.getPointer(),\n                timestamp,\n                interval,\n                values.length,\n                values);\n    }\n\n    /**\n     * A simple structure for saving a timestamp and a value.\n     * <p>\n     * Equivalent to GstTimedValue.\n     * <p>\n     * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstControlSource.html#GstTimedValue\"\n     * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstControlSource.html#GstTimedValue</a>\n     *\n     */\n    public static final class TimedValue {\n\n        public final long timestamp;\n        public final double value;\n\n        /**\n         * Create a TimedValue wrapping the timestamp (see {@link ClockTime})\n         * and corresponding value.\n         *\n         * @param timestamp the timestamp (GstClockTime) of the value change\n         * @param value the corresponding value\n         */\n        public TimedValue(long timestamp, double value) {\n            this.timestamp = timestamp;\n            this.value = value;\n        }\n\n        @Override\n        public int hashCode() {\n            int hash = 7;\n            hash = 37 * hash + (int) (this.timestamp ^ (this.timestamp >>> 32));\n            hash = 37 * hash + (int) (Double.doubleToLongBits(this.value) ^ (Double.doubleToLongBits(this.value) >>> 32));\n            return hash;\n        }\n\n        @Override\n        public boolean equals(Object obj) {\n            if (this == obj) {\n                return true;\n            }\n            if (obj == null) {\n                return false;\n            }\n            if (getClass() != obj.getClass()) {\n                return false;\n            }\n            final TimedValue other = (TimedValue) obj;\n            if (this.timestamp != other.timestamp) {\n                return false;\n            }\n            if (Double.doubleToLongBits(this.value) != Double.doubleToLongBits(other.value)) {\n                return false;\n            }\n            return true;\n        }\n\n        @Override\n        public String toString() {\n            return \"TimedValue{\" + \"timestamp=\" + timestamp + \", value=\" + value + '}';\n        }\n\n    }\n\n    protected static class Handle extends GstObject.Handle {\n\n        public Handle(GstControlSourcePtr ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n\n        @Override\n        protected GstControlSourcePtr getPointer() {\n            return (GstControlSourcePtr) super.getPointer();\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/DateTime.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2016 Christophe Lafolet\n * Copyright (c) 2010 Levente Farkas\n * \n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstDateTimeAPI.GSTDATETIME_API;\n\nimport org.freedesktop.gstreamer.glib.NativeObject;\n\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.lowlevel.GPointer;\n\n/**\n */\npublic class DateTime extends NativeObject {\n\n    public static final String GTYPE_NAME = \"GstDateTime\";\n\n    public static DateTime createInstanceLocalEpoch(long secs) {\n        return new DateTime(GSTDATETIME_API.gst_date_time_new_from_unix_epoch_local_time(secs), false, true);\n    }\n\n    DateTime(Initializer init) {\n        this(new Handle(init.ptr, init.ownsHandle));\n    }\n\n    DateTime(Pointer ptr, boolean needRef, boolean ownsHandle) {\n        this(new Handle(new GPointer(ptr), ownsHandle));\n    }\n    \n    DateTime(Handle handle) {\n        super(handle);\n    }\n\n    public int getYear() {\n        return GSTDATETIME_API.gst_date_time_get_year(getRawPointer());\n    }\n\n    public int getMonth() {\n        return GSTDATETIME_API.gst_date_time_get_month(getRawPointer());\n    }\n\n    public int getDay() {\n        return GSTDATETIME_API.gst_date_time_get_day(getRawPointer());\n    }\n\n    public int getHour() {\n        return GSTDATETIME_API.gst_date_time_get_hour(getRawPointer());\n    }\n\n    public int getMinute() {\n        return GSTDATETIME_API.gst_date_time_get_minute(getRawPointer());\n    }\n\n    public int getSecond() {\n        return GSTDATETIME_API.gst_date_time_get_second(getRawPointer());\n    }\n\n    public int getMicrosecond() {\n        return GSTDATETIME_API.gst_date_time_get_microsecond(getRawPointer());\n    }\n\n    @Override\n    public String toString() {\n        return \"\" + getYear() + \"-\" + getMonth() + \"-\" + getDay() + \" \" + getHour() + \":\" + getMinute() + \":\" + getSecond() + \".\" + getMicrosecond();\n    }\n\n    private static final class Handle extends NativeObject.Handle {\n\n        public Handle(GPointer ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n\n        @Override\n        protected void disposeNativeHandle(GPointer ptr) {\n            GSTDATETIME_API.gst_date_time_unref(ptr.getPointer());\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/Element.java",
    "content": "/* \n * Copyright (c) 2025 Neil C Smith\n * Copyright (c) 2019 Christophe Lafolet\n * Copyright (c) 2009 Levente Farkas\n * Copyright (C) 2007 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2004 Wim Taymans <wim@fluendo.com>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport java.util.List;\nimport java.util.Set;\nimport java.util.concurrent.TimeUnit;\nimport org.freedesktop.gstreamer.event.Event;\nimport org.freedesktop.gstreamer.event.SeekEvent;\nimport org.freedesktop.gstreamer.event.SeekFlags;\nimport org.freedesktop.gstreamer.event.SeekType;\nimport org.freedesktop.gstreamer.glib.NativeFlags;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback;\nimport org.freedesktop.gstreamer.lowlevel.GstContextPtr;\nimport org.freedesktop.gstreamer.lowlevel.GstIteratorPtr;\nimport org.freedesktop.gstreamer.lowlevel.GstObjectPtr;\nimport org.freedesktop.gstreamer.message.Message;\nimport org.freedesktop.gstreamer.query.Query;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstElementAPI.GSTELEMENT_API;\nimport static org.freedesktop.gstreamer.lowlevel.GObjectAPI.GOBJECT_API;\n\n/**\n * Abstract base class for all pipeline elements.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/documentation/gstreamer/gstelement.html\"\n * >https://gstreamer.freedesktop.org/documentation/gstreamer/gstelement.html</a>\n * <p>\n * Element is the abstract base class needed to construct an element that can be\n * used in a GStreamer pipeline. Please refer to the plugin writers guide for\n * more information on creating Element subclasses.\n * <p>\n * The name of a Element can be retrieved with {@link #getName} and set with\n * {@link #setName}.\n * <p>\n * All elements have pads (of the type {@link Pad}). These pads link to pads on\n * other elements. {@link Buffer}s flow between these linked pads. An Element\n * has a list of {@link Pad} structures for all their input (or sink) and output\n * (or source) pads. Core and plug-in writers can add and remove pads with\n * {@link #addPad} and {@link #removePad}.\n * <p>\n * Elements can be linked through their pads. If the link is straightforward,\n * use the {@link #link} convenience function to link two elements, or\n * {@link #linkMany} for more elements in a row.\n * <p>\n * For finer control, use {@link #linkPads} and {@link #linkPadsFiltered} to\n * specify the pads to link on each element by name.\n * <p>\n * Each element has a state (see {@link State}). You can get and set the state\n * of an element with {@link #getState} and {@link #setState}.\n *\n */\npublic class Element extends GstObject {\n\n    public static final String GTYPE_NAME = \"GstElement\";\n\n    /**\n     * Creates a new instance of Element. This constructor is used internally.\n     *\n     * @param init internal initialization data.\n     */\n    protected Element(Initializer init) {\n        super(init);\n    }\n\n    Element(Handle handle, boolean needRef) {\n        super(handle, needRef);\n    }\n\n    /**\n     * Creates an instance of the required element type, but does not wrap it in\n     * a proxy.\n     *\n     * @param factoryName The name of the factory to use to produce the Element\n     * @param elementName The name to assign to the created Element\n     * @return a raw element.\n     */\n    protected static Initializer makeRawElement(String factoryName, String elementName) {\n        return Natives.initializer(ElementFactory.makeRawElement(factoryName, elementName));\n    }\n\n    /**\n     * Links this element to another element. The link must be from source to\n     * destination; the other direction will not be tried.\n     * <p>\n     * The function looks for existing pads that aren't linked yet. It will\n     * request new pads if necessary. Such pads need to be released manually\n     * when unlinking. If multiple links are possible, only one is established.\n     * <p>\n     * Make sure you have added your elements to a bin or pipeline with\n     * {@link Bin#add} or {@link Bin#addMany} before trying to link them.\n     * <p>\n     * See {@link #linkPadsFiltered} if you need more control about which pads\n     * are selected for linking.\n     *\n     * @param dest The element containing the destination pad.\n     * @return true if the elements could be linked, false otherwise.\n     */\n    public boolean link(Element dest) {\n        return GSTELEMENT_API.gst_element_link(this, dest);\n    }\n\n    /**\n     * Links this element to another element using the given caps as filtercaps.\n     * The link must be from source to destination; the other direction will not\n     * be tried.\n     * <p>\n     * The function looks for existing pads that aren't linked yet. It will\n     * request new pads if necessary. Such pads need to be released manually\n     * when unlinking. If multiple links are possible, only one is established.\n     * <p>\n     * Make sure you have added your elements to a bin or pipeline with\n     * {@link Bin#add} or {@link Bin#addMany} before trying to link them.\n     * <p>\n     * See {@link #linkPadsFiltered} if you need more control about which pads\n     * are selected for linking.\n     *\n     * @param dest The element containing the destination pad.\n     * @param filter The {@link Caps} to filter the link, or Null for no filter.\n     * @return true if the elements could be linked, false otherwise.\n     */\n    public boolean linkFiltered(Element dest, Caps filter) {\n        return GSTELEMENT_API.gst_element_link_filtered(this, dest, filter);\n    }\n\n    /**\n     * Unlinks all source pads of this source element with all sink pads of the\n     * sink element to which they are linked.\n     * <p>\n     * If the link has been made using {@link #link}, it could have created an\n     * requestpad, which has to be released using\n     * gst_element_release_request_pad().\n     *\n     * @param dest The sink Element to unlink.\n     */\n    public void unlink(Element dest) {\n        GSTELEMENT_API.gst_element_unlink(this, dest);\n    }\n\n    /**\n     * Tests if the Element is currently playing.\n     *\n     * @return true if the Element is currently playing\n     */\n    public boolean isPlaying() {\n        return getState() == State.PLAYING;\n    }\n\n    /**\n     * Tells the Element to start playing the media stream. Equivalent to\n     * calling {@link #setState(org.freedesktop.gstreamer.State)} with\n     * {@link State#PLAYING}.\n     *\n     * @return the status of the element's state change.\n     */\n    public StateChangeReturn play() {\n        return setState(State.PLAYING);\n    }\n\n    /**\n     * Tells the Element to set ready the media stream. Equivalent to calling\n     * {@link #setState(org.freedesktop.gstreamer.State)} with\n     * {@link State#READY}.\n     *\n     * @return the status of the element's state change.\n     */\n    public StateChangeReturn ready() {\n        return setState(State.READY);\n    }\n\n    /**\n     * Tells the Element to pause playing the media stream. Equivalent to\n     * calling {@link #setState(org.freedesktop.gstreamer.State)} with\n     * {@link State#PAUSED}.\n     *\n     * @return the status of the element's state change.\n     */\n    public StateChangeReturn pause() {\n        return setState(State.PAUSED);\n    }\n\n    /**\n     * Tells the Element to stop playing the media stream. Equivalent to calling\n     * {@link #setState(org.freedesktop.gstreamer.State)} with\n     * {@link State#NULL}.\n     *\n     * @return the status of the element's state change.\n     */\n    public StateChangeReturn stop() {\n        return setState(State.NULL);\n    }\n\n    /**\n     * Sets the state of the element.\n     * <p>\n     * This method will try to set the requested state by going through all the\n     * intermediary states.\n     * <p>\n     * This function can return {@link StateChangeReturn#ASYNC}, in which case\n     * the element will perform the remainder of the state change asynchronously\n     * in another thread.\n     * <p>\n     * An application can use {@link #getState} to wait for the completion of\n     * the state change or it can wait for a state change message on the bus.\n     *\n     * @param state the element's new {@link State}.\n     * @return the status of the element's state change.\n     */\n    public StateChangeReturn setState(State state) {\n        return GSTELEMENT_API.gst_element_set_state(this, state);\n    }\n\n    /**\n     * Locks the state of an element, so state changes of the parent don't\n     * affect this element anymore.\n     *\n     * @param locked_state true to lock the element's {@link State}.\n     * @return true if the state was changed, false if bad parameters were given\n     * or the elements state-locking needed no change.\n     */\n    public boolean setLockedState(boolean locked_state) {\n        return GSTELEMENT_API.gst_element_set_locked_state(this, locked_state);\n    }\n\n    /**\n     * Gets the state of the element.\n     * <p>\n     * This method will wait until any async state change has completed.\n     *\n     * @return The {@link State} the Element is currently in.\n     */\n    public State getState() {\n        return getState(-1);\n    }\n\n    /**\n     * Gets the state of the element.\n     * <p>\n     * For elements that performed an ASYNC state change, as reported by\n     * {@link #setState(org.freedesktop.gstreamer.State)}, this function will\n     * block up to the specified timeout value for the state change to complete.\n     *\n     * @param timeout the amount of time to wait.\n     * @param units the units of the <tt>timeout</tt>.\n     * @return The {@link State} the Element is currently in.\n     *\n     */\n    public State getState(long timeout, TimeUnit units) {\n        State[] state = new State[1];\n        GSTELEMENT_API.gst_element_get_state(this, state, null, units.toNanos(timeout));\n        return state[0];\n    }\n\n    /**\n     * Gets the state of the element.\n     * <p>\n     * For elements that performed an ASYNC state change, as reported by\n     * {@link #setState(org.freedesktop.gstreamer.State)}, this function will\n     * block up to the specified timeout value for the state change to complete.\n     *\n     * @param timeout The amount of time in nanoseconds to wait.\n     * @return The {@link State} the Element is currently in.\n     *\n     */\n    public State getState(long timeout) {\n        State[] state = new State[1];\n        GSTELEMENT_API.gst_element_get_state(this, state, null, timeout);\n        return state[0];\n    }\n\n    /**\n     * Gets the state of the element.\n     * <p>\n     * For elements that performed an ASYNC state change, as reported by\n     * {@link #setState(org.freedesktop.gstreamer.State)}, this function will\n     * block up to the specified timeout value for the state change to complete.\n     *\n     * @param timeout The amount of time in nanoseconds to wait.\n     * @param states an array to store the states in. Must be of sufficient size\n     * to hold two elements.\n     */\n    public void getState(long timeout, State[] states) {\n        State[] state = new State[1];\n        State[] pending = new State[1];\n        GSTELEMENT_API.gst_element_get_state(this, state, pending, timeout);\n        states[0] = state[0];\n        states[1] = pending[0];\n    }\n\n    /**\n     * Tries to change the state of the element to the same as its parent. If\n     * this function returns false, the state of element is undefined.\n     *\n     * @return true, if the element's state could be synced to the parent's\n     * state. MT safe.\n     */\n    public boolean syncStateWithParent() {\n        return GSTELEMENT_API.gst_element_sync_state_with_parent(this);\n    }\n\n    /**\n     * Sets the {@link Caps} on this Element.\n     *\n     * @param caps the new Caps to set.\n     */\n    public void setCaps(Caps caps) {\n        GOBJECT_API.g_object_set(this, \"caps\", caps);\n    }\n\n    /**\n     * Retrieves a pad from the element by name. This version only retrieves\n     * already-existing (i.e. 'static') pads.\n     *\n     * @param padname The name of the {@link Pad} to get.\n     * @return The requested {@link Pad} if found, otherwise null.\n     */\n    public Pad getStaticPad(String padname) {\n        return GSTELEMENT_API.gst_element_get_static_pad(this, padname);\n    }\n\n    /**\n     * Retrieves a list of the element's pads.\n     *\n     * @return the List of {@link Pad}s.\n     */\n    public List<Pad> getPads() {\n        return padList(GSTELEMENT_API.gst_element_iterate_pads(this));\n    }\n\n    /**\n     * Retrieves a list of the element's source pads.\n     *\n     * @return the List of {@link Pad}s.\n     */\n    public List<Pad> getSrcPads() {\n        return padList(GSTELEMENT_API.gst_element_iterate_src_pads(this));\n    }\n\n    /**\n     * Retrieves a list of the element's sink pads.\n     *\n     * @return the List of {@link Pad}s.\n     */\n    public List<Pad> getSinkPads() {\n        return padList(GSTELEMENT_API.gst_element_iterate_sink_pads(this));\n    }\n\n    private List<Pad> padList(GstIteratorPtr iter) {\n        return GstIterator.asList(iter, Pad.class);\n    }\n\n    /**\n     * Adds a {@link Pad} (link point) to the Element. The Pad's parent will be\n     * set to this element.\n     * <p>\n     * Pads are not automatically activated so elements should perform the\n     * needed steps to activate the pad in case this pad is added in the PAUSED\n     * or PLAYING state. See {@link Pad#setActive} for more information about\n     * activating pads.\n     * <p>\n     * This function will emit the {@link PAD_ADDED} signal on the element.\n     *\n     * @param pad The {@link Pad} to add.\n     * @return true if the pad could be added. This function can fail when a pad\n     * with the same name already existed or the pad already had another parent.\n     */\n    public boolean addPad(Pad pad) {\n        return GSTELEMENT_API.gst_element_add_pad(this, pad);\n    }\n\n    /**\n     * Retrieves a pad from the element by name. This version only retrieves\n     * request pads. The pad must be released with {@link #releaseRequestPad}.\n     *\n     * @param name the name of the request {@link Pad} to retrieve.\n     * @return the requested Pad if found, otherwise <tt>null</tt>. Release\n     * using {@link #releaseRequestPad} after usage.\n     */\n    public Pad getRequestPad(String name) {\n        return GSTELEMENT_API.gst_element_get_request_pad(this, name);\n    }\n\n    /**\n     * Frees the previously requested pad obtained via {@link #getRequestPad}.\n     *\n     * @param pad the pad to release.\n     */\n    public void releaseRequestPad(Pad pad) {\n        GSTELEMENT_API.gst_element_release_request_pad(this, pad);\n    }\n\n    /**\n     * Remove a {@link Pad} from the element.\n     * <p>\n     * This method is used by plugin developers and should not be used by\n     * applications. Pads that were dynamically requested from elements with\n     * {@link #getRequestPad} should be released with the\n     * {@link #releaseRequestPad} function instead.\n     * <p>\n     * Pads are not automatically deactivated so elements should perform the\n     * needed steps to deactivate the pad in case this pad is removed in the\n     * PAUSED or PLAYING state. See {@link Pad#setActive} for more information\n     * about deactivating pads.\n     * <p>\n     * This function will emit the {@link PAD_REMOVED} signal on the element.\n     *\n     * @param pad The {@link Pad} to remove.\n     * @return true if the pad could be removed. Can return false if the pad\n     * does not belong to the provided element.\n     */\n    public boolean removePad(Pad pad) {\n        return GSTELEMENT_API.gst_element_remove_pad(this, pad);\n    }\n\n    /**\n     * Retrieves the factory that was used to create this element.\n     *\n     * @return the {@link ElementFactory} used for creating this element.\n     */\n    public ElementFactory getFactory() {\n        return GSTELEMENT_API.gst_element_get_factory(this);\n    }\n\n    /**\n     * Get the bus of the element. Note that only a {@link Pipeline} will\n     * provide a bus for the application.\n     *\n     * @return the element's {@link Bus}\n     */\n    public Bus getBus() {\n        return GSTELEMENT_API.gst_element_get_bus(this);\n    }\n\n    /**\n     * Sends an event to an element.\n     * <p>\n     * If the element doesn't implement an event handler, the event will be\n     * pushed on a random linked sink pad for upstream events or a random linked\n     * source pad for downstream events.\n     *\n     * @param ev The {@link Event} to send.\n     * @return true if the event was handled.\n     */\n    public boolean sendEvent(Event ev) {\n        return GSTELEMENT_API.gst_element_send_event(this, ev);\n    }\n\n    /**\n     * Signal emitted when an {@link Pad} is added to this element.\n     *\n     * @see #connect(PAD_ADDED)\n     * @see #disconnect(PAD_ADDED)\n     */\n    public static interface PAD_ADDED {\n\n        /**\n         * Called when a new {@link Pad} is added to an Element.\n         *\n         * @param element the element the pad was added to.\n         * @param pad the pad which was added.\n         */\n        public void padAdded(Element element, Pad pad);\n    }\n\n    /**\n     * Signal emitted when an {@link Pad} is removed from this element.\n     *\n     * @see #connect(PAD_REMOVED)\n     * @see #disconnect(PAD_REMOVED)\n     */\n    public static interface PAD_REMOVED {\n\n        /**\n         * Called when a new {@link Pad} is removed from an Element.\n         *\n         * @param element the element the pad was removed from.\n         * @param pad the pad which was removed.\n         */\n        public void padRemoved(Element element, Pad pad);\n    }\n\n    /**\n     * Signal emitted when this element ceases to generated dynamic pads.\n     *\n     * @see #connect(NO_MORE_PADS)\n     * @see #disconnect(NO_MORE_PADS)\n     */\n    public static interface NO_MORE_PADS {\n\n        /**\n         * Called when an element ceases to generated dynamic pads.\n         *\n         * @param element the element which posted this message.\n         */\n        public void noMorePads(Element element);\n    }\n\n    /**\n     * Add a listener for the <code>pad-added</code> signal\n     *\n     * @param listener Listener to be called when a {@link Pad} is added to the\n     * element.\n     */\n    public void connect(final PAD_ADDED listener) {\n        connect(PAD_ADDED.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(Element elem, Pad pad) {\n                listener.padAdded(elem, pad);\n            }\n        });\n    }\n\n    /**\n     * Remove a listener for the <code>pad-added</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(PAD_ADDED listener) {\n        disconnect(PAD_ADDED.class, listener);\n    }\n\n    /**\n     * Add a listener for the <code>pad-added</code> signal\n     *\n     * @param listener Listener to be called when a {@link Pad} is removed from\n     * the element.\n     */\n    public void connect(final PAD_REMOVED listener) {\n        connect(PAD_REMOVED.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(Element elem, Pad pad) {\n                listener.padRemoved(elem, pad);\n            }\n        });\n    }\n\n    /**\n     * Remove a listener for the <code>pad-removed</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(PAD_REMOVED listener) {\n        disconnect(PAD_REMOVED.class, listener);\n    }\n\n    /**\n     * Add a listener for the <code>no-more-pads</code> signal\n     *\n     * @param listener Listener to be called when the element has finished\n     * generating dynamic pads.\n     */\n    public void connect(final NO_MORE_PADS listener) {\n        connect(NO_MORE_PADS.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(Element elem) {\n                listener.noMorePads(elem);\n            }\n        });\n    }\n\n    /**\n     * Remove a listener for the <code>no-more-pads</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(NO_MORE_PADS listener) {\n        disconnect(NO_MORE_PADS.class, listener);\n    }\n\n    /**\n     * Link together a list of elements.\n     * <p>\n     * Make sure you have added your elements to a bin or pipeline with\n     * {@link Bin#add} or {@link Bin#addMany} before trying to link them.\n     *\n     * @param elements The list of elements to link together.\n     * @return true if all elements successfully linked.\n     */\n    public static boolean linkMany(Element... elements) {\n        return GSTELEMENT_API.gst_element_link_many(elements);\n    }\n\n    /**\n     * Unlink a list of elements.\n     *\n     * @param elements The list of elements to link together\n     *\n     */\n    public static void unlinkMany(Element... elements) {\n        GSTELEMENT_API.gst_element_unlink_many(elements);\n    }\n\n    /**\n     * Link together source and destination pads of two elements.\n     *\n     * A side effect is that if one of the pads has no parent, it becomes a\n     * child of the parent of the other element. If they have different parents,\n     * the link fails.\n     *\n     * @param src The element containing the source {@link Pad}.\n     * @param srcPadName The name of the source {@link Pad}. Can be null for any\n     * pad.\n     * @param dest The element containing the destination {@link Pad}.\n     * @param destPadName The name of the destination {@link Pad}. Can be null\n     * for any pad.\n     *\n     * @return true if the pads were successfully linked.\n     */\n    public static boolean linkPads(Element src, String srcPadName, Element dest, String destPadName) {\n        return GSTELEMENT_API.gst_element_link_pads(src, srcPadName, dest, destPadName);\n    }\n\n    /**\n     * Link together source and destination pads of two elements. A side effect\n     * is that if one of the pads has no parent, it becomes a child of the\n     * parent of the other element. If they have different parents, the link\n     * fails. If caps is not null, makes sure that the caps of the link is a\n     * subset of caps.\n     *\n     * @param src The element containing the source {@link Pad}.\n     * @param srcPadName The name of the source {@link Pad}. Can be null for any\n     * pad.\n     * @param dest The element containing the destination {@link Pad}.\n     * @param destPadName The name of the destination {@link Pad}. Can be null\n     * for any pad.\n     * @param caps The {@link Caps} to use to filter the link.\n     *\n     * @return true if the pads were successfully linked.\n     */\n    public static boolean linkPadsFiltered(Element src, String srcPadName,\n            Element dest, String destPadName, Caps caps) {\n        return GSTELEMENT_API.gst_element_link_pads_filtered(src, srcPadName, dest, destPadName, caps);\n    }\n\n    /**\n     * Unlink source and destination pads of two elements.\n     *\n     * @param src The element containing the source {@link Pad}.\n     * @param srcPadName The name of the source {@link Pad}.\n     * @param dest The element containing the destination {@link Pad}.\n     * @param destPadName The name of the destination {@link Pad}.\n     *\n     */\n    public static void unlinkPads(Element src, String srcPadName, Element dest, String destPadName) {\n        GSTELEMENT_API.gst_element_unlink_pads(src, srcPadName, dest, destPadName);\n    }\n\n    /**\n     * Posts a {@link Message} on the element's {@link Bus}.\n     *\n     * @param message the Message to post.\n     * @return <tt>true</tt> if the message was posted, <tt>false</tt> if the\n     * element does not have a {@link Bus}.\n     */\n    public boolean postMessage(Message message) {\n        return GSTELEMENT_API.gst_element_post_message(this, message);\n    }\n\n    /**\n     * Gets the currently configured clock of the element.\n     *\n     * @return the clock of the element.\n     */\n    public Clock getClock() {\n        return GSTELEMENT_API.gst_element_get_clock(this);\n    }\n\n    /**\n     * Returns the base time of the element. The base time is the absolute time\n     * of the clock when this element was last put to PLAYING. Subtracting the\n     * base time from the clock time gives the stream time of the element.\n     *\n     * @return the base time of the element\n     */\n    public long getBaseTime() {\n        return GSTELEMENT_API.gst_element_get_base_time(this);\n    }\n\n    /**\n     * Set the base time of an element.\n     *\n     * @param time the base time to set\n     * @see #getBaseTime()\n     */\n    public void setBaseTime(long time) {\n        GSTELEMENT_API.gst_element_set_base_time(this, time);\n    }\n\n    /**\n     * Returns the start time of this element.\n     *\n     * The start time is the running time of the clock when this element was\n     * last put to {@link State#PAUSED}. Usually the start_time is managed by a\n     * toplevel element such as {@link Pipeline}.\n     *\n     * MT safe.\n     *\n     * @return the start time of this element.\n     */\n    public long getStartTime() {\n        return GSTELEMENT_API.gst_element_get_start_time(this);\n    }\n\n    /**\n     * Set the start time of an element. The start time of the element is the\n     * running time of the element when it last went to the {@link State#PAUSED}\n     * state. In {@link State#READY} or after a flushing seek, it is set to 0.\n     *\n     * Toplevel elements like GstPipeline will manage the start_time and\n     * base_time on its children. Setting the start_time to\n     * {@link ClockTime#NONE} on such a toplevel element will disable the\n     * distribution of the base_time to the children and can be useful if the\n     * application manages the base_time itself, for example if you want to\n     * synchronize capture from multiple pipelines, and you can also ensure that\n     * the pipelines have the same clock.\n     *\n     * MT safe.\n     *\n     * @param time the start time to set\n     * @see #getStartTime()\n     */\n    public void setStartTime(long time) {\n        GSTELEMENT_API.gst_element_set_start_time(this, time);\n    }\n\n    /**\n     * Performs a query on the element.\n     *\n     * For elements that don't implement a query handler, this function forwards\n     * the query to a random srcpad or to the peer of a random linked sinkpad of\n     * this element.\n     *\n     * Please note that some queries might need a running pipeline to work.\n     *\n     * @param query the Query to perform\n     * @return true if the query could be performed\n     */\n    public boolean query(Query query) {\n        return GSTELEMENT_API.gst_element_query(this, query);\n    }\n\n    /**\n     * Sets the context of the element.\n     *\n     * @param context the Context to set.\n     */\n    public void setContext(Context context) {\n        GstContextPtr gstContextPtr = Natives.getPointer(context).as(GstContextPtr.class, GstContextPtr::new);\n        GSTELEMENT_API.gst_element_set_context(this, gstContextPtr);\n    }\n\n    /**\n     * Gets the context with the context_type set on the element or NULL.\n     *\n     * @param context_type\n     * @return a context or NULL\n     */\n    public Context getContext(String context_type) {\n        GstContextPtr gstContextPtr = GSTELEMENT_API.gst_element_get_context(this, context_type);\n        return gstContextPtr != null ? Natives.callerOwnsReturn(gstContextPtr, Context.class) : null;\n    }\n\n    /**\n     * Queries an element (usually top-level pipeline or playbin element) for\n     * the total stream duration in nanoseconds. This query will only work once\n     * the pipeline is prerolled (i.e. reached PAUSED or PLAYING state). The\n     * application will receive an ASYNC_DONE message on the pipeline bus when\n     * that is the case.\n     * <p>\n     * If the duration changes for some reason, you will get a DURATION_CHANGED\n     * message on the pipeline bus, in which case you should re-query the\n     * duration using this function.\n     *\n     * @param format the {@code Format} to return the duration in\n     * @return the total duration of the current media stream, or -1 if the\n     * query failed\n     */\n    public long queryDuration(Format format) {\n        long[] dur = {0};\n        return GSTELEMENT_API.gst_element_query_duration(this, format, dur) ? dur[0] : -1L;\n    }\n\n    /**\n     * Queries an element (usually top-level pipeline or playbin element) for\n     * the stream position in nanoseconds. This will be a value between 0 and\n     * the stream duration (if the stream duration is known). This query will\n     * usually only work once the pipeline is prerolled (i.e. reached PAUSED or\n     * PLAYING state). The application will receive an ASYNC_DONE message on the\n     * pipeline bus when that is the case.\n     *\n     * @param format The {@link Format} to return the position in\n     * @return the current position or -1 if the query failed.\n     */\n    public long queryPosition(Format format) {\n        long[] pos = {0};\n        return GSTELEMENT_API.gst_element_query_position(this, format, pos) ? pos[0] : -1L;\n    }\n\n    /**\n     * Sends a seek event to an element. See {@link SeekEvent} for the details\n     * of the parameters. The seek event is sent to the element using the native\n     * equivalent of {@link #sendEvent(org.freedesktop.gstreamer.event.Event)}.\n     *\n     * @param rate the new playback rate\n     * @param format the format of the seek values\n     * @param seekFlags the seek flags\n     * @param startType the type and flags for the new start position\n     * @param start the value of the new start position\n     * @param stopType the type and flags for the new stop position\n     * @param stop the value of the new stop position\n     * @return true if seek operation succeeded. Flushing seeks will trigger a\n     * preroll, which will emit an ASYNC_DONE message\n     */\n    public boolean seek(double rate, Format format, Set<SeekFlags> seekFlags,\n            SeekType startType, long start, SeekType stopType, long stop) {\n\n        return GSTELEMENT_API.gst_element_seek(this, rate, format,\n                NativeFlags.toInt(seekFlags), startType, start, stopType, stop);\n    }\n\n    /**\n     * Simple API to perform a seek on the given element, meaning it just seeks\n     * to the given position relative to the start of the stream. For more\n     * complex operations like segment seeks (e.g. for looping) or changing the\n     * playback rate or seeking relative to the last configured playback segment\n     * you should use\n     * {@link #seek(double, org.freedesktop.gstreamer.Format, java.util.Set, org.freedesktop.gstreamer.event.SeekType, long, org.freedesktop.gstreamer.event.SeekType, long)}.\n     * <p>\n     * In a completely prerolled PAUSED or PLAYING pipeline, seeking is always\n     * guaranteed to return TRUE on a seekable media type or FALSE when the\n     * media type is certainly not seekable (such as a live stream).\n     * <p>\n     * Some elements allow for seeking in the READY state, in this case they\n     * will store the seek event and execute it when they are put to PAUSED. If\n     * the element supports seek in READY, it will always return TRUE when it\n     * receives the event in the READY state.\n     *\n     * @param format a {@link Format} to seek in, such as {@link Format#TIME}\n     * @param seekFlags seek options; playback applications will usually want to\n     * use {@link SeekFlags#FLUSH} and {@link SeekFlags#KEY_UNIT} here\n     * @param seekPosition position to seek to (relative to the start); if you\n     * are doing a seek in format TIME this value is in nanoseconds\n     * @return true if seek operation succeeded. Flushing seeks will trigger a\n     * preroll, which will emit an ASYNC_DONE message\n     */\n    public boolean seekSimple(Format format, Set<SeekFlags> seekFlags, long seekPosition) {\n        return GSTELEMENT_API.gst_element_seek_simple(this, format,\n                NativeFlags.toInt(seekFlags), seekPosition);\n    }\n\n    static class Handle extends GstObject.Handle {\n\n        public Handle(GstObjectPtr ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/ElementFactory.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstElementFactoryAPI.GSTELEMENTFACTORY_API;\nimport static org.freedesktop.gstreamer.lowlevel.GstPadTemplateAPI.GSTPADTEMPLATE_API;\nimport static org.freedesktop.gstreamer.lowlevel.GstPluginAPI.GSTPLUGIN_API;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI.GList;\nimport org.freedesktop.gstreamer.lowlevel.GstPadTemplateAPI.GstStaticPadTemplate;\n\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.glib.Natives;\n\n/**\n * ElementFactory is used to create instances of elements.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstElementFactory.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstElementFactory.html</a>\n * <p>\n * Use the {@link #find} and {@link #create} methods to create element instances\n * or use {@link #make} as a convenient shortcut.\n *\n */\npublic class ElementFactory extends PluginFeature {\n\n    public static final String GTYPE_NAME = \"GstElementFactory\";\n    \n    private static final Level DEBUG = Level.FINE;\n    private static final Logger LOG = Logger.getLogger(ElementFactory.class.getName());\n\n    /**\n     * Creates a new instance of ElementFactory\n     *\n     * @param init internal initialization data.\n     */\n    ElementFactory(Initializer init) {\n        super(init);\n        if (LOG.isLoggable(Level.FINER)) {\n            LOG.entering(\"ElementFactory\", \"<init>\", new Object[]{init});\n        }\n    }\n\n    /**\n     * Creates a new element from the factory.\n     *\n     * @param name the name to assign to the created Element\n     * @return A new {@link Element}\n     */\n    public Element create(String name) {\n        if (LOG.isLoggable(Level.FINER)) {\n            LOG.entering(\"ElementFactory\", \"create\", name);\n        }\n        Pointer elem = GSTELEMENTFACTORY_API.ptr_gst_element_factory_create(this, name);\n        LOG.log(DEBUG, \"gst_element_factory_create returned: \" + elem);\n        if (elem == null) {\n            throw new IllegalArgumentException(\"Cannot create GstElement\");\n        }\n        return elementFor(elem, getName());\n    }\n\n    /**\n     * Returns the name of the person who wrote the factory.\n     *\n     * @return The name of the author\n     */\n    public String getAuthor() {\n        if (LOG.isLoggable(Level.FINER)) {\n            LOG.entering(\"ElementFactory\", \"getAuthor\");\n        }\n        return GSTELEMENTFACTORY_API.gst_element_factory_get_metadata(this, \"author\");\n    }\n\n    /**\n     * Returns a description of the factory.\n     *\n     * @return A brief description of the factory.\n     */\n    public String getDescription() {\n        if (LOG.isLoggable(Level.FINER)) {\n            LOG.entering(\"ElementFactory\", \"getDescription\");\n        }\n        return GSTELEMENTFACTORY_API.gst_element_factory_get_metadata(this, \"description\");\n    }\n\n    /**\n     * Returns a string describing the type of factory. This is an unordered\n     * list separated with slashes ('/').\n     *\n     * @return The description of the type of factory.\n     */\n    public String getKlass() {\n        if (LOG.isLoggable(Level.FINER)) {\n            LOG.entering(\"ElementFactory\", \"getKlass\");\n        }\n        return GSTELEMENTFACTORY_API.gst_element_factory_get_metadata(this, \"klass\");\n    }\n\n    /**\n     * Returns the long, English name for the factory.\n     *\n     * @return The long, English name for the factory.\n     */\n    public String getLongName() {\n        if (LOG.isLoggable(Level.FINER)) {\n            LOG.entering(\"ElementFactory\", \"getLongName\");\n        }\n        return GSTELEMENTFACTORY_API.gst_element_factory_get_metadata(this, \"long-name\");\n    }\n\n    /**\n     * Gets the list of {@link StaticPadTemplate} for this factory.\n     *\n     * @return The list of {@link StaticPadTemplate}\n     */\n    public List<StaticPadTemplate> getStaticPadTemplates() {\n        if (LOG.isLoggable(Level.FINER)) {\n            LOG.entering(\"ElementFactory\", \"getStaticPadTemplates\");\n        }\n        GList glist = GSTELEMENTFACTORY_API.gst_element_factory_get_static_pad_templates(this);\n        LOG.log(DEBUG, \"GSTELEMENTFACTORY_API.gst_element_factory_get_static_pad_templates returned: \" + glist);\n        List<StaticPadTemplate> templates = new ArrayList<StaticPadTemplate>();\n        GList next = glist;\n        while (next != null) {\n            if (next.data != null) {\n                GstStaticPadTemplate temp = new GstStaticPadTemplate(next.data);\n                templates.add(new StaticPadTemplate(temp.getName(), temp.getPadDirection(),\n                        temp.getPadPresence(), GSTPADTEMPLATE_API.gst_static_pad_template_get_caps(temp)));\n            }\n            next = next.next();\n        }\n        return templates;\n    }\n\n    /**\n     * Retrieve an instance of a factory that can produce {@link Element}s\n     *\n     * @param name The type of {@link Element} to produce.\n     * @return An ElementFactory that will produce {@link Element}s of the\n     * desired type.\n     */\n    public static ElementFactory find(String name) {\n        if (LOG.isLoggable(Level.FINER)) {\n            LOG.entering(\"ElementFactory\", \"find\", name);\n        }\n        ElementFactory factory = GSTELEMENTFACTORY_API.gst_element_factory_find(name);\n        if (factory == null) {\n            throw new IllegalArgumentException(\"No such Gstreamer factory: \" + name);\n        }\n        return factory;\n    }\n\n//    /**\n//     * Filter out all the elementfactories in list that can handle caps in the\n//     * given direction.\n//     *\n//     * If subsetonly is true, then only the elements whose pads templates are a\n//     * complete superset of caps will be returned. Else any element whose pad\n//     * templates caps can intersect with caps will be returned.\n//     *\n//     * @param list a {@link List} of {@link ElementFactory} to filter\n//     * @param caps a {@link Caps}\n//     * @param direction a {@link PadDirection} to filter on\n//     * @param subsetonly whether to filter on caps subsets or not.\n//     * @return a {@link List} of {@link ElementFactory} elements that match the\n//     * given requisits.\n//     */\n//    public static List<ElementFactory> listFilter(List<ElementFactory> list, Caps caps,\n//            PadDirection direction, boolean subsetonly) {\n//        GList glist = null;\n//        List<ElementFactory> filterList = new ArrayList<ElementFactory>();\n//\n//        for (ElementFactory fact : list) {\n//            fact.ref();\n//            glist = GLIB_API.g_list_append(glist, fact.handle());\n//        }\n//\n//        GList gFilterList = GSTELEMENTFACTORY_API.gst_element_factory_list_filter(glist, caps, direction, subsetonly);\n//\n//        GList next = gFilterList;\n//        while (next != null) {\n//            if (next.data != null) {\n//                ElementFactory fact = new ElementFactory(initializer(next.data, true, true));\n//                filterList.add(fact);\n//            }\n//            next = next.next();\n//        }\n//\n//        GSTPLUGIN_API.gst_plugin_list_free(glist);\n//        GSTPLUGIN_API.gst_plugin_list_free(gFilterList);\n//\n//        return filterList;\n//    }\n\n    /**\n     * Get a list of factories that match the given type. Only elements with a\n     * rank greater or equal to minrank will be returned. The list of factories\n     * is returned by decreasing rank.\n     *\n     * @param type a {@link ListType}\n     * @param minrank Minimum rank\n     * @return a List of ElementFactory elements.\n     */\n    public static List<ElementFactory> listGetElements(ListType type, Rank minrank) {\n        GList glist = GSTELEMENTFACTORY_API.gst_element_factory_list_get_elements(type.getValue(), minrank.intValue());\n        List<ElementFactory> list = new ArrayList<ElementFactory>();\n\n        GList next = glist;\n        while (next != null) {\n            if (next.data != null) {\n                ElementFactory fact = new ElementFactory(Natives.initializer(next.data, true, true));\n                list.add(fact);\n            }\n            next = next.next();\n        }\n\n        GSTPLUGIN_API.gst_plugin_list_free(glist);\n\n        return list;\n    }\n\n    /**\n     * Get a list of factories that match the given parameter.\n     *\n     * It is a combination of listGetElement and listFilter passing all the\n     * results of the first call to the second.\n     *\n     * This method improves performance because there is no need to map to java\n     * list the elements returned by the first call.\n     *\n     * @param type a {@link ListType}\n     * @param minrank Minimum rank\n     * @param caps a {@link Caps}\n     * @param direction a {@link PadDirection} to filter on\n     * @param subsetonly whether to filter on caps subsets or not.\n     * @return a {@link List} of {@link ElementFactory} elements that match the\n     * given requisits.\n     */\n    public static List<ElementFactory> listGetElementsFilter(ListType type, Rank minrank,\n            Caps caps, PadDirection direction, boolean subsetonly) {\n        List<ElementFactory> filterList = new ArrayList<ElementFactory>();\n\n        GList glist = GSTELEMENTFACTORY_API.gst_element_factory_list_get_elements(type.getValue(), minrank.intValue());\n\n        GList gFilterList = GSTELEMENTFACTORY_API.gst_element_factory_list_filter(glist, caps, direction, subsetonly);\n\n        GList next = gFilterList;\n        while (next != null) {\n            if (next.data != null) {\n                ElementFactory fact = new ElementFactory(Natives.initializer(next.data, true, true));\n                filterList.add(fact);\n            }\n            next = next.next();\n        }\n\n        GSTPLUGIN_API.gst_plugin_list_free(glist);\n        GSTPLUGIN_API.gst_plugin_list_free(gFilterList);\n\n        return filterList;\n    }\n\n    /**\n     * Creates a new Element from the specified factory.\n     *\n     * @param factoryName The name of the factory to use to produce the Element\n     * @param name The name to assign to the created Element\n     * @return A new GstElemElement\n     */\n    public static Element make(String factoryName, String name) {\n        if (LOG.isLoggable(Level.FINER)) {\n            LOG.entering(\"ElementFactory\", \"make\", new Object[]{factoryName, name});\n        }\n        return elementFor(makeRawElement(factoryName, name), factoryName);\n    }\n\n    static Pointer makeRawElement(String factoryName, String name) {\n        if (LOG.isLoggable(Level.FINER)) {\n            LOG.entering(\"ElementFactory\", \"makeRawElement\", new Object[]{factoryName, name});\n        }\n        Pointer elem = GSTELEMENTFACTORY_API.ptr_gst_element_factory_make(factoryName, name);\n        LOG.log(DEBUG, \"Return from gst_element_factory_make=\" + elem);\n        if (elem == null) {\n            throw new IllegalArgumentException(\"No such Gstreamer factory: \"\n                    + factoryName);\n        }\n        return elem;\n    }\n\n    private static Element elementFor(Pointer ptr, String factoryName) {\n        return Natives.objectFor(ptr, Element.class, false, true);\n    }\n\n    /**\n     * The type of ElementFactory to filter.\n     */\n    public enum ListType {\n\n        /** Decoder elements */\n        DECODER((long) 1 << 0),\n        /** Encoder elements */\n        ENCODER((long) 1 << 1),\n        /** Sink elements */\n        SINK((long) 1 << 2),\n        /** Source elements */\n        SRC((long) 1 << 3),\n        /** Muxer elements */\n        MUXER((long) 1 << 4),\n        /** Demuxer elements */\n        DEMUXER((long) 1 << 5),\n        /** Parser elements */        \n        PARSER((long) 1 << 6),\n        /** Payloader elements */\n        PAYLOADER((long) 1 << 7),\n        /** Depayloader elements */\n        DEPAYLOADER((long) 1 << 8),\n        /** Formatter elements */\n        FORMATTER((long) 1 << 9),\n        /** Decryptor elements */\n        DECRYPTOR((long) 1 << 10),\n        /** Encryptor elements */\n        ENCRYPTOR((long) 1 << 11),\n//        /** Private, do not use */\n//        MAX_ELEMENTS((long) 1 << 48),\n        /** Any elements */\n        ANY((((long) 1) << 49) - 1),\n        /** Any of the defined media element types */\n        MEDIA_ANY(~((long) 0) << 48),\n        /** Elements handling video media types */\n        MEDIA_VIDEO((long) 1 << 49),\n        /** Elements handling audio media types */\n        MEDIA_AUDIO((long) 1 << 50),\n        /** Elements handling image media types */\n        MEDIA_IMAGE((long) 1 << 51),\n        /** Elements handling subtitle media types */\n        MEDIA_SUBTITLE((long) 1 << 52),\n        /** Elements handling metadata media types */\n        MEDIA_METADATA((long) 1 << 53),\n        /** All encoders handling video or image media types */\n        VIDEO_ENCODER(ENCODER.getValue() | MEDIA_VIDEO.getValue() | MEDIA_IMAGE.getValue()),\n        /** All encoders handling audio media types */\n        AUDIO_ENCODER(ENCODER.getValue() | MEDIA_AUDIO.getValue()),\n        /** All sinks handling audio, video or image media types */\n        AUDIOVIDEO_SINKS(SINK.getValue() | MEDIA_AUDIO.getValue() | MEDIA_VIDEO.getValue() | MEDIA_IMAGE.getValue()),\n        /** All elements used to 'decode' streams (decoders, demuxers, parsers, depayloaders) */\n        DECODABLE(DECODER.getValue() | DEMUXER.getValue() | DEPAYLOADER.getValue() | PARSER.getValue());\n\n        private final long value;\n\n        private ListType(long value) {\n            this.value = value;\n        }\n\n        public long getValue() {\n            return value;\n        }\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/FlowReturn.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2007 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wim.taymans@chello.be>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.NativeEnum;\nimport org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue;\n\n/**\n * The result of passing data to a pad.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPad.html#GstFlowReturn\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPad.html#GstFlowReturn</a>\n * <p>\n */\npublic enum FlowReturn implements NativeEnum<FlowReturn> {\n\n    /** Data passing was ok. */\n    // @TODO need to map custom success and custom error OK and ERROR?\n    @DefaultEnumValue\n    OK(0),\n\n    /** {@link Pad} is not linked. */\n    NOT_LINKED(-1),\n    /** {@link Pad} is in wrong state. */\n    FLUSHING(-2),\n    /** Did not expect anything, like after EOS. */\n    EOS(-3),\n    /** {@link Pad} is in not negotiated. */\n    NOT_NEGOTIATED(-4),\n    \n    /**\n     * Some (fatal) error occured. Element generating this error should post \n     * an error message with more details.\n     */\n    ERROR(-5),\n    \n    /** This operation is not supported. */\n    NOT_SUPPORTED(-6);\n    \n    private final int value;\n    \n    FlowReturn(int value) {\n        this.value = value;\n    }\n    \n    /**\n     * Gets the integer value of the enum.\n     * @return The integer value for this enum.\n     */\n    @Override\n    public int intValue() {\n        return value;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/Format.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.NativeEnum;\nimport org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue;\n\n/**\n * Standard predefined formats.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/gstreamer-GstFormat.html#GstFormat\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/gstreamer-GstFormat.html#GstFormat</a>\n * <p>\n */\n// @TODO this won't handle custom registered formats - do we need to?\npublic enum Format implements NativeEnum<Format> {\n    /** Undefined format */\n    @DefaultEnumValue\n    UNDEFINED(0),\n    /**\n     * The default format of the pad/element. This can be samples for raw audio,\n     * frames/fields for raw video (some, but not all, elements support this;\n     * use {@link #TIME } if you don't have a good reason to query for\n     * samples/frames)\n     */\n    DEFAULT(1),\n    /** Bytes */\n    BYTES(2),\n    /** Time in nanoseconds */\n    TIME(3),\n    \n    /** {@link Buffer}s (few, if any, elements implement this as of May 2009) */\n    BUFFERS(4),\n    /** Percentage of stream (few, if any, elements implement this as of May 2009) */\n    PERCENT(5);\n\n    private final int value;\n    \n    Format(int value) {\n        this.value = value;\n    }\n    \n    @Override\n    public int intValue() {\n        return value;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/Fraction.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007,2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\n/**\n * Represents a fraction value.\n */\npublic class Fraction {\n    public final int numerator;\n    public final int denominator;\n    \n    /**\n     * Creates a new {@code Fraction}.\n     * \n     * @param numerator the numerator value.\n     * @param denominator the denominator value.\n     */\n    public Fraction(int numerator, int denominator) {\n        this.numerator = numerator;\n        this.denominator = denominator;\n    }\n    \n    /**\n     * Gets the numerator of the {@code Fraction}\n     * \n     * @return the numerator as an integer.\n     */\n    public int getNumerator() {\n        return numerator;\n    }\n    \n    /**\n     * Gets the denominator of the {@code Fraction}\n     * \n     * @return the denominator as an integer.\n     */\n    public int getDenominator() {\n        return denominator;\n    }\n    \n    /**\n     * Returns the fraction as a floating point value (numerator divided by the denominator).\n     * @return fraction as a <code>double</code>, or <code>Double.NaN</code> if the denominator is 0\n     */\n    public double toDouble() {\n    \treturn denominator != 0 ? ((double) numerator / denominator) : Double.NaN;\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/GhostPad.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (C) 2007 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wtay@chello.be>\n *                    2005 Andy Wingo <wingo@pobox.com>\n *\t\t      2006 Edward Hervey <bilboed@bilboed.com>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.Natives;\nimport static org.freedesktop.gstreamer.lowlevel.GstGhostPadAPI.GSTGHOSTPAD_API;\n\n/**\n * Pseudo link pads.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstGhostPad.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstGhostPad.html</a>\n * <p>\n * GhostPads are useful when organizing pipelines with {@link Bin} like\n * elements. The idea here is to create hierarchical element graphs. The bin\n * element contains a sub-graph. Now one would like to treat the bin-element\n * like any other {@link Element}. This is where GhostPads come into play. A\n * GhostPad acts as a proxy for another pad. Thus the bin can have sink and\n * source ghost-pads that are associated with sink and source pads of the child\n * elements.\n * <p>\n * If the target pad is known at creation time, {@link #GhostPad(String, Pad)}\n * is the function to use to get a ghost-pad. Otherwise one can use\n * {@link #GhostPad(String, PadDirection)} to create the ghost-pad and use\n * {@link #setTarget} to establish the association later on.\n * <p>\n * Note that GhostPads add overhead to the data processing of a pipeline.\n *\n * @see Pad\n */\npublic class GhostPad extends Pad {\n\n    public static final String GTYPE_NAME = \"GstGhostPad\";\n\n    /**\n     * Creates a new instance of GhostPad\n     */\n    GhostPad(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Create a new ghostpad with target as the target. The direction will be\n     * taken from the target pad. The target pad must be unlinked.\n     *\n     * @param name The name of the new pad, or null to assign a default name.\n     * @param target The {@link Pad} to ghost.\n     */\n    public GhostPad(String name, Pad target) {\n        this(Natives.initializer(GSTGHOSTPAD_API.ptr_gst_ghost_pad_new(name, target)));\n    }\n\n    /**\n     * Create a new ghostpad with target as the target. The direction will be\n     * taken from the target pad. The template used on the ghostpad will be\n     * template.\n     *\n     * @param name The name of the new pad, or null to assign a default name.\n     * @param target The {@link Pad} to ghost.\n     * @param template The {@link PadTemplate} to use on the ghostpad.\n     */\n    public GhostPad(String name, Pad target, PadTemplate template) {\n        this(Natives.initializer(GSTGHOSTPAD_API.ptr_gst_ghost_pad_new_from_template(name, target, template)));\n    }\n\n    /**\n     * Create a new ghostpad without a target with the given direction. A target\n     * can be set on the ghostpad later with the {@link #setTarget} method.\n     * <p>\n     * The created ghostpad will not have a padtemplate.\n     *\n     * @param name The name of the new pad, or null to assign a default name.\n     * @param direction The direction of the ghostpad.\n     */\n    public GhostPad(String name, PadDirection direction) {\n        this(Natives.initializer(GSTGHOSTPAD_API.ptr_gst_ghost_pad_new_no_target(name, direction.ordinal())));\n    }\n\n    /**\n     * Create a new ghostpad based on template, without setting a target. The\n     * direction will be taken from the template.\n     *\n     * @param name The name of the new pad, or null to assign a default name.\n     * @param template The {@link PadTemplate} to use on the ghostpad.\n     */\n    public GhostPad(String name, PadTemplate template) {\n        this(Natives.initializer(GSTGHOSTPAD_API.ptr_gst_ghost_pad_new_no_target_from_template(name, template)));\n    }\n\n    /**\n     * Get the target pad of this ghostpad.\n     *\n     * @return the target {@link Pad}, can be null if the ghostpad has no target\n     * set\n     */\n    public Pad getTarget() {\n        return GSTGHOSTPAD_API.gst_ghost_pad_get_target(this);\n    }\n\n    /**\n     * Set the new target of the ghostpad. Any existing target is unlinked and\n     * links to the new target are established.\n     *\n     * @param pad The new pad target.\n     * @return true if the new target could be set. This function can return\n     * false when the internal pads could not be linked.\n     */\n    public boolean setTarget(Pad pad) {\n        return GSTGHOSTPAD_API.gst_ghost_pad_set_target(this, pad);\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/Gst.java",
    "content": "/* \n * Copyright (c) 2025 Neil C Smith\n * Copyright (c) 2018 Antonio Morales\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.query.Query;\nimport org.freedesktop.gstreamer.message.Message;\nimport org.freedesktop.gstreamer.event.Event;\nimport org.freedesktop.gstreamer.glib.GError;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstAPI.GST_API;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.ScheduledExecutorService;\nimport java.util.concurrent.ThreadFactory;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicInteger;\nimport java.util.logging.Logger;\n\nimport org.freedesktop.gstreamer.glib.MainContextExecutorService;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GErrorStruct;\nimport org.freedesktop.gstreamer.lowlevel.GstTypes;\nimport org.freedesktop.gstreamer.glib.NativeObject;\n\nimport com.sun.jna.Memory;\nimport com.sun.jna.Native;\nimport com.sun.jna.Pointer;\nimport com.sun.jna.ptr.IntByReference;\nimport com.sun.jna.ptr.PointerByReference;\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.util.ServiceLoader;\nimport java.util.logging.Level;\nimport java.util.stream.Stream;\nimport org.freedesktop.gstreamer.controller.Controllers;\nimport org.freedesktop.gstreamer.elements.Elements;\nimport org.freedesktop.gstreamer.glib.GLib;\nimport org.freedesktop.gstreamer.glib.GMainContext;\nimport org.freedesktop.gstreamer.video.Video;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstParseAPI.GSTPARSE_API;\nimport static org.freedesktop.gstreamer.glib.Natives.registration;\nimport static org.freedesktop.gstreamer.lowlevel.GlibAPI.GLIB_API;\n\nimport org.freedesktop.gstreamer.webrtc.WebRTC;\n\n/**\n * Media library supporting arbitrary formats and filter graphs.\n */\npublic final class Gst {\n    \n    private final static Logger LOG = Logger.getLogger(Gst.class.getName());\n    private final static AtomicInteger INIT_COUNT = new AtomicInteger(0);\n    private final static boolean CHECK_VERSIONS = !Boolean.getBoolean(\"gstreamer.suppressVersionChecks\");\n    private final static boolean DISABLE_EXTERNAL = Boolean.getBoolean(\"gstreamer.disableExternalTypes\");\n    \n    private static ScheduledExecutorService executorService;\n    private static volatile CountDownLatch quit = new CountDownLatch(1);\n    private static GMainContext mainContext;\n    private static boolean useDefaultContext = false;\n    private static List<Runnable> shutdownTasks = Collections.synchronizedList(new ArrayList<Runnable>());\n    // set minorVersion to a value guaranteed to be >= anything else unless set in init()\n    private static int minorVersion = Integer.MAX_VALUE;\n    \n    private static class NativeArgs {\n        \n        public IntByReference argcRef;\n        public PointerByReference argvRef;\n        Memory[] argsCopy;\n        Memory argvMemory;\n        \n        public NativeArgs(String progname, String[] args) {\n            //\n            // Allocate some native memory to pass the args down to the native layer\n            //\n            argsCopy = new Memory[args.length + 2];\n            argvMemory = new Memory(argsCopy.length * Native.POINTER_SIZE);\n\n            //\n            // Insert the program name as argv[0]\n            //\n            Memory arg = new Memory(progname.getBytes().length + 4);\n            arg.setString(0, progname);\n            argsCopy[0] = arg;\n            \n            for (int i = 0; i < args.length; i++) {\n                arg = new Memory(args[i].getBytes().length + 1);\n                arg.setString(0, args[i]);\n                argsCopy[i + 1] = arg;\n            }\n            argvMemory.write(0, argsCopy, 0, argsCopy.length);\n            argvRef = new PointerByReference(argvMemory);\n            argcRef = new IntByReference(args.length + 1);\n        }\n        \n        String[] toStringArray() {\n            //\n            // Unpack the native arguments back into a String array\n            //\n            List<String> args = new ArrayList<String>();\n            Pointer argv = argvRef.getValue();\n            for (int i = 1; i < argcRef.getValue(); i++) {\n                Pointer arg = argv.getPointer(i * Native.POINTER_SIZE);\n                if (arg != null) {\n                    args.add(arg.getString(0));\n                }\n            }\n            return args.toArray(new String[args.size()]);\n        }\n    }\n\n    private Gst() {\n    }\n\n    /**\n     * Gets the version of gstreamer currently available. This function can be\n     * used prior to calling {@link #init(org.freedesktop.gstreamer.Version) }\n     *\n     * @return the version of gstreamer\n     */\n    public static Version getVersion() {\n        long[] major = {0}, minor = {0}, micro = {0}, nano = {0};\n        GST_API.gst_version(major, minor, micro, nano);\n        return new Version((int) major[0], (int) minor[0], (int) micro[0], (int) nano[0]);\n    }\n\n    /**\n     * Gets the the version of gstreamer currently in use, as a String.\n     *\n     * @return a string representation of the version.\n     */\n    public static String getVersionString() {\n        return GST_API.gst_version_string();\n    }\n\n    /**\n     * Some functions in the GStreamer core might install a custom SIGSEGV\n     * handler to better catch and report errors to the application. Currently\n     * this feature is enabled by default when loading plugins.\n     * <p>\n     * Applications might want to disable this behaviour with the\n     * {@link #setSegTrap(boolean) } function. This is typically done if the\n     * application wants to install its own handler without GStreamer\n     * interfering.\n     *\n     * @return Segmentation Trap status.\n     */\n    public static boolean isSegTrapEnabled() {\n        return GST_API.gst_segtrap_is_enabled();\n    }\n\n    /**\n     * Applications might want to disable/enable the SIGSEGV handling of the\n     * GStreamer core. See {@link #isSegTrapEnabled() } for more information.\n     *\n     * @param enabled\n     */\n    public static void setSegTrap(boolean enabled) {\n        GST_API.gst_segtrap_set_enabled(enabled);\n    }\n\n    /**\n     * Test whether the GStreamer library already initialized.\n     *\n     * @return true if the GStreamer library already initialized.\n     */\n    public static synchronized final boolean isInitialized() {\n        return INIT_COUNT.get() > 0;\n    }\n\n    /**\n     * Gets the common {@link ScheduledExecutorService} used to execute\n     * background tasks and schedule timeouts.\n     *\n     * @return an executor that can be used for background tasks.\n     */\n    public static ScheduledExecutorService getExecutor() {\n        return executorService;\n    }\n\n    /**\n     * Signals the thread that called {@link #init} to return.\n     */\n    public static void quit() {\n        quit.countDown();\n    }\n\n    /**\n     * Create a new pipeline based on command line syntax.\n     *\n     * Please note that you might get a return value that is not NULL even\n     * though the error is set. In this case there was a recoverable parsing\n     * error and you can try to play the pipeline.\n     *\n     * @param pipelineDescription the command line describing the pipeline\n     * @param errors a list that any errors will be added to\n     * @return a new element on success. If more than one top-level element is\n     * specified by the pipeline_description , all elements are put into a\n     * Pipeline, which then is returned.\n     * @throws GstException if the pipeline / element could not be created\n     */\n    public static Element parseLaunch(String pipelineDescription, List<GError> errors) {\n        Pointer[] err = {null};\n        Element pipeline = GSTPARSE_API.gst_parse_launch(pipelineDescription, err);\n        if (pipeline == null) {\n            throw new GstException(extractError(err[0]));\n        }\n\n        // check for error\n        if (err[0] != null) {\n            if (errors != null) {\n                errors.add(extractError(err[0]));\n            } else {\n                LOG.log(Level.WARNING, extractError(err[0]).getMessage());\n            }\n        }\n        \n        return pipeline;\n    }\n\n    /**\n     * Create a new pipeline based on command line syntax.\n     *\n     * Please note that you might get a return value that is not NULL even\n     * though the error is set. In this case there was a recoverable parsing\n     * error and you can try to play the pipeline.\n     *\n     * @param pipelineDescription the command line describing the pipeline\n     * @return a new element on success. If more than one top-level element is\n     * specified by the pipeline_description , all elements are put into a\n     * Pipeline, which then is returned.\n     * @throws GstException if the pipeline / element could not be created\n     */\n    public static Element parseLaunch(String pipelineDescription) {\n        return parseLaunch(pipelineDescription, null);\n    }\n\n    /**\n     * Create a new element based on command line syntax.\n     *\n     * error will contain an error message if an erroneous pipeline is\n     * specified. An error does not mean that the pipeline could not be\n     * constructed.\n     *\n     * @param pipelineDescription An array of strings containing the command\n     * line describing the pipeline.\n     * @param errors a list that any errors will be added to\n     * @return a new element on success.\n     * @throws GstException if the pipeline / element could not be created\n     */\n    public static Element parseLaunch(String[] pipelineDescription, List<GError> errors) {\n        Pointer[] err = {null};\n        Element pipeline = GSTPARSE_API.gst_parse_launchv(pipelineDescription, err);\n        if (pipeline == null) {\n            throw new GstException(extractError(err[0]));\n        }\n\n        // check for error\n        if (err[0] != null) {\n            if (errors != null) {\n                errors.add(extractError(err[0]));\n            } else {\n                LOG.log(Level.WARNING, extractError(err[0]).getMessage());\n            }\n        }\n        \n        return pipeline;\n    }\n\n    /**\n     * Create a new element based on command line syntax.\n     *\n     * error will contain an error message if an erroneous pipeline is\n     * specified. An error does not mean that the pipeline could not be\n     * constructed.\n     *\n     * @param pipelineDescription An array of strings containing the command\n     * line describing the pipeline.\n     * @return a new element on success.\n     * @throws GstException if the pipeline / element could not be created\n     */\n    public static Element parseLaunch(String[] pipelineDescription) {\n        return parseLaunch(pipelineDescription, null);\n    }\n\n    /**\n     * Creates a bin from a text bin description.\n     *\n     * This function allows creation of a bin based on the syntax used in the\n     * gst-launch utillity.\n     *\n     * @param binDescription the command line describing the bin\n     * @param ghostUnlinkedPads whether to create ghost pads for the bin from\n     * any unlinked pads\n     * @param errors list that any errors will be added to\n     * @return The new Bin.\n     * @throws GstException if the bin could not be created\n     */\n    public static Bin parseBinFromDescription(String binDescription, boolean ghostUnlinkedPads, List<GError> errors) {\n        \n        Pointer[] err = {null};\n        Bin bin = GSTPARSE_API.gst_parse_bin_from_description(binDescription, ghostUnlinkedPads, err);\n        \n        if (bin == null) {\n            throw new GstException(extractError(err[0]));\n        }\n\n        // check for error\n        if (err[0] != null) {\n            if (errors != null) {\n                errors.add(extractError(err[0]));\n            } else {\n                LOG.log(Level.WARNING, extractError(err[0]).getMessage());\n            }\n        }\n        \n        return bin;\n    }\n\n    /**\n     * Creates a bin from a text bin description.\n     *\n     * This function allows creation of a bin based on the syntax used in the\n     * gst-launch utillity.\n     *\n     * @param binDescription the command line describing the bin\n     * @param ghostUnlinkedPads whether to create ghost pads for the bin from\n     * any unlinked pads\n     * @return The new Bin.\n     * @throws GstException if the bin could not be created\n     */\n    public static Bin parseBinFromDescription(String binDescription, boolean ghostUnlinkedPads) {\n        return parseBinFromDescription(binDescription, ghostUnlinkedPads, null);\n    }\n    \n    private static GError extractError(Pointer errorPtr) {\n        GErrorStruct struct = new GErrorStruct(errorPtr);\n        struct.read();\n        GError err = new GError(struct.getCode(), struct.getMessage());\n        GLIB_API.g_error_free(errorPtr);\n        return err;\n    }\n\n    /**\n     * Waits for the gstreamer system to shutdown via a call to {@link #quit}.\n     * <p>\n     * For most gui programs, this is of little use. However, it can be a\n     * convenient way of keeping the main thread alive whilst gstreamer\n     * processing on other threads continues.\n     */\n    public static void main() {\n        try {\n            CountDownLatch latch = quit;\n            if (latch != null) {\n                latch.await();\n            }\n        } catch (InterruptedException ex) {\n        } finally {\n            quit = new CountDownLatch(1);\n        }\n    }\n\n    /**\n     * Schedules a task for execution on the gstreamer background\n     * {@link java.util.concurrent.Executor}.\n     *\n     * @param task the task to execute.\n     */\n    public static void invokeLater(final Runnable task) {\n        getExecutor().execute(task);\n    }\n\n\n    /**\n     * Gets the current main context used (if any).\n     *\n     * @return a main context.\n     */\n    // @TODO leaking lowlevel\n    public static GMainContext getMainContext() {\n        return mainContext;\n    }\n\n    /**\n     * Initializes the GStreamer library.\n     * <p>\n     * This is a shortcut if no arguments are to be passed to gstreamer.\n     * <p>\n     * <b>This is equivalent to calling\n     * {@link #init(org.freedesktop.gstreamer.Version) } with\n     * {@link Version#BASELINE}, currently GStreamer 1.8.</b> If you require\n     * features from a later version of GStreamer you should specify the\n     * required version.\n     *\n     * @throws org.freedesktop.gstreamer.GstException\n     */\n    public static final void init() throws GstException {\n        init(Version.BASELINE, \"gst1-java-core\");\n    }\n\n    /**\n     * Initializes the GStreamer library.\n     * <p>\n     * This is a shortcut if no arguments are to be passed to gstreamer.\n     *\n     * @param requiredVersion\n     * @throws org.freedesktop.gstreamer.GstException\n     */\n    public static final void init(Version requiredVersion) throws GstException {\n        init(requiredVersion, \"gst1-java-core\");\n    }\n\n    /**\n     * Initializes the GStreamer library.\n     * <p>\n     * This sets up internal path lists, registers built-in elements, and loads\n     * standard plugins.\n     * <p>\n     * <b>This is equivalent to calling\n     * {@link #init(org.freedesktop.gstreamer.Version, java.lang.String, java.lang.String...) }\n     * with {@link Version#BASELINE}, currently GStreamer 1.8.</b> If you\n     * require features from a later version of GStreamer you should specify the\n     * required version.\n     *\n     * @param progname the java program name.\n     * @param args the java argument list.\n     * @return the list of arguments with any gstreamer specific options\n     * stripped out.\n     * @throws org.freedesktop.gstreamer.GstException\n     */\n    public static synchronized final String[] init(String progname, String... args) throws GstException {\n        return init(Version.BASELINE, progname, args);\n    }\n\n    /**\n     * Initializes the GStreamer library.\n     * <p>\n     * This sets up internal path lists, registers built-in elements, and loads\n     * standard plugins.\n     *\n     * @param requestedVersion the minimum requested GStreamer version.\n     * @param progname the java program name.\n     * @param args the java argument list.\n     * @return the list of arguments with any gstreamer specific options\n     * stripped out.\n     * @throws org.freedesktop.gstreamer.GstException\n     */\n    public static synchronized final String[] init(Version requestedVersion,\n            String progname, String... args) throws GstException {\n        \n        if (CHECK_VERSIONS) {\n            Version availableVersion = getVersion();\n            if (requestedVersion.getMajor() != 1 || availableVersion.getMajor() != 1) {\n                throw new GstException(\"gst1-java-core only supports GStreamer 1.x\");\n            }\n            if (requestedVersion.getMinor() < 8) {\n                requestedVersion = new Version(1, 8);\n            }\n            if (!availableVersion.checkSatisfies(requestedVersion)) {\n                throw new GstException(String.format(\n                        \"The requested version of GStreamer is not available\\nRequested : %s\\nAvailable : %s\\n\",\n                        requestedVersion, availableVersion));\n            }\n        }\n\n        //\n        // Only do real init the first time through\n        //\n        if (INIT_COUNT.getAndIncrement() > 0) {\n            if (CHECK_VERSIONS) {\n                if (requestedVersion.getMinor() > minorVersion) {\n                    minorVersion = (int) requestedVersion.getMinor();\n                }\n            }\n            return args;\n        }\n        \n        NativeArgs argv = new NativeArgs(progname, args);\n        \n        Pointer[] error = {null};\n        if (!GST_API.gst_init_check(argv.argcRef, argv.argvRef, error)) {\n            INIT_COUNT.decrementAndGet();\n            throw new GstException(extractError(error[0]));\n        }\n        \n        LOG.fine(\"after gst_init, argc=\" + argv.argcRef.getValue());\n        \n        Version runningVersion = getVersion();\n        if (runningVersion.getMajor() != 1) {\n            LOG.warning(\"gst1-java-core only supports GStreamer 1.x\");\n        }\n        \n        if (useDefaultContext) {\n            mainContext = GMainContext.getDefaultContext();\n            executorService = new MainContextExecutorService(mainContext);\n        } else {\n            mainContext = new GMainContext();\n            executorService = Executors.newSingleThreadScheduledExecutor(threadFactory);\n        }\n        quit = new CountDownLatch(1);\n        loadAllClasses();\n        \n        if (CHECK_VERSIONS) {\n            minorVersion = requestedVersion.getMinor();\n        }\n        \n        return argv.toStringArray();\n    }\n\n    /**\n     * Clean up any resources created by GStreamer in\n     * {@link #init(org.freedesktop.gstreamer.Version)}.\n     *\n     * <b>It is normally not needed to call this function in a normal\n     * application as the resources will automatically be freed when the program\n     * terminates. This function is therefore mostly used by testsuites and\n     * other memory profiling tools.</b>\n     *\n     * After this call GStreamer (including this method) should not be used\n     * anymore.\n     */\n    public static synchronized final void deinit() {\n        //\n        // Only perform real shutdown if called as many times as Gst.init() is\n        //\n        if (INIT_COUNT.decrementAndGet() > 0) {\n            return;\n        }\n        // Perform any cleanup tasks\n        for (Object task : shutdownTasks.toArray()) {\n            ((Runnable) task).run();\n        }\n\n        // Stop any more tasks/timers from being scheduled\n        executorService.shutdown();\n\n        // Wake up the run thread.\n        quit();\n\n        // Wait for tasks to complete.\n        try {\n            if (!executorService.awaitTermination(100, TimeUnit.MILLISECONDS)) {\n                // Force-kill everything\n                executorService.shutdownNow();\n            }\n        } catch (InterruptedException ex) {\n        }\n        \n        mainContext = null;\n        System.gc(); // Make sure any dangling objects are unreffed before calling deinit().\n        GST_API.gst_deinit();\n    }\n\n    /**\n     * Adds a task to be called when {@link Gst#deinit} is called.\n     * <p>\n     * This is used internally, and is not recommended for other uses.\n     *\n     * @param task the task to execute.\n     */\n    static void addStaticShutdownTask(Runnable task) {\n        shutdownTasks.add(task);\n    }\n\n    /**\n     * Instructs gstreamer-java to use the default main context.\n     * <p>\n     * This may be useful if integration with the GTK main loop is desirable, as\n     * all {@link Bus} signals and timers will be executed in the context of the\n     * GTK main loop.\n     * <p>\n     * For the majority of programs though, it is better to wrap the individual\n     * listeners in a proxy which executes the listener in the appropriate\n     * context.\n     *\n     * @param useDefault if true, use the default glib main context.\n     */\n    public static void setUseDefaultContext(boolean useDefault) {\n        useDefaultContext = useDefault;\n    }\n\n    /**\n     * Checks that the version of GStreamer requested in init() satisfies the\n     * given version or throws an exception.\n     *\n     * @param major major version, only 1 is supported\n     * @param minor minor version required\n     * @throws GstException if the requested version support was not requested\n     */\n    public static void checkVersion(int major, int minor) {\n        if (CHECK_VERSIONS && (major != 1 || minor > minorVersion)) {\n            throw new GstException(\"Not supported by requested GStreamer version\");\n        }\n    }\n\n    /**\n     * Tests that the version of GStreamer requested in init() satisfies the\n     * given version.\n     *\n     * @param major major version, only 1 is supported\n     * @param minor minor version required\n     * @return boolean whether the version requirement can be satisfied\n     */\n    public static boolean testVersion(int major, int minor) {\n        if (CHECK_VERSIONS && (major != 1 || minor > minorVersion)) {\n            return false;\n        }\n        return true;\n    }\n\n    // Make the gstreamer executor threads daemon, so they don't stop the main \n    // program from exiting\n    private static final ThreadFactory threadFactory = new ThreadFactory() {\n        private final AtomicInteger counter = new AtomicInteger(0);\n\n        @Override\n        public Thread newThread(Runnable task) {\n            final String name = \"gstreamer service thread \" + counter.incrementAndGet();\n            Thread t = new Thread(task, name);\n            t.setDaemon(true);\n            t.setPriority(Thread.NORM_PRIORITY);\n            return t;\n        }\n    };\n    \n    private static synchronized void loadAllClasses() {\n        Stream.of(new GLib.Types(),\n                new Types(),\n                new Event.Types(),\n                new Message.Types(),\n                new Query.Types(),\n                new Controllers(),\n                new Elements(),\n                new WebRTC.Types(),\n                new Video.Types())\n                .flatMap(NativeObject.TypeProvider::types)\n                .forEachOrdered(GstTypes::register);\n        if (!DISABLE_EXTERNAL) {\n            try {\n                ServiceLoader<NativeObject.TypeProvider> extProviders\n                        = ServiceLoader.load(NativeObject.TypeProvider.class);\n                extProviders.iterator().forEachRemaining(prov\n                        -> prov.types().forEachOrdered(GstTypes::register));\n            } catch (Throwable t) {\n                LOG.log(Level.SEVERE, \"Error during external types registration\", t);\n            }\n        }\n    }\n    \n    public static class Types implements NativeObject.TypeProvider {\n        \n        @Override\n        public Stream<NativeObject.TypeRegistration<?>> types() {\n            return Stream.of(\n                    registration(Bin.class, Bin.GTYPE_NAME, Bin::new),\n                    registration(Buffer.class, Buffer.GTYPE_NAME, Buffer::new),\n                    registration(BufferPool.class, BufferPool.GTYPE_NAME, BufferPool::new),\n                    registration(Bus.class, Bus.GTYPE_NAME, Bus::new),\n                    registration(Caps.class, Caps.GTYPE_NAME, Caps::new),\n                    registration(Clock.class, Clock.GTYPE_NAME, Clock::new),\n                    registration(Context.class, Context.GTYPE_NAME, Context::new),\n                    registration(DateTime.class, DateTime.GTYPE_NAME, DateTime::new),\n                    registration(Element.class, Element.GTYPE_NAME, Element::new),\n                    registration(ElementFactory.class, ElementFactory.GTYPE_NAME, ElementFactory::new),\n                    registration(GhostPad.class, GhostPad.GTYPE_NAME, GhostPad::new),\n                    registration(Pad.class, Pad.GTYPE_NAME, Pad::new),\n                    registration(PadTemplate.class, PadTemplate.GTYPE_NAME, PadTemplate::new),\n                    registration(Pipeline.class, Pipeline.GTYPE_NAME, Pipeline::new),\n                    registration(Plugin.class, Plugin.GTYPE_NAME, Plugin::new),\n                    registration(PluginFeature.class, PluginFeature.GTYPE_NAME, PluginFeature::new),\n                    registration(Promise.class, Promise.GTYPE_NAME, Promise::new),\n                    registration(Registry.class, Registry.GTYPE_NAME, Registry::new),\n                    registration(SDPMessage.class, SDPMessage.GTYPE_NAME, SDPMessage::new),\n                    registration(Sample.class, Sample.GTYPE_NAME, Sample::new),\n                    registration(Structure.class, Structure.GTYPE_NAME, Structure::new),\n                    registration(TagList.class, TagList.GTYPE_NAME, TagList::new)\n            );\n        }\n        \n    }\n\n    /**\n     * Annotation on classes, methods or fields to show the required GStreamer\n     * version. This should particularly be used where the version required is\n     * higher than the current baseline supported version (GStreamer 1.8)\n     */\n    @Retention(RetentionPolicy.RUNTIME)\n    @Documented\n    public static @interface Since {\n        \n        public int major() default 1;\n        \n        public int minor();\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/GstException.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.GError;\nimport org.freedesktop.gstreamer.glib.GLibException;\n\n/**\n * Thrown when a GStreamer error occurs.\n */\npublic class GstException extends GLibException {\n\n    private static final long serialVersionUID = -7413580400835548033L;\n\n    /**\n     * Creates a new instance of <code>GstException</code> without detail message.\n     */\n    public GstException() {\n    }\n\n\n    /**\n     * Constructs an instance of <code>GstException</code> with the specified detail message.\n     * \n     * @param msg the detail message.\n     */\n    public GstException(String msg) {\n        super(msg);\n    }\n    \n    public GstException(GError error) {\n        super(error);\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/GstIterator.java",
    "content": "/* \n * Copyright (c) 2021 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.freedesktop.gstreamer.glib.NativeObject;\nimport org.freedesktop.gstreamer.lowlevel.GstIteratorPtr;\nimport org.freedesktop.gstreamer.lowlevel.GstTypes;\nimport org.freedesktop.gstreamer.lowlevel.GType;\nimport org.freedesktop.gstreamer.lowlevel.GValueAPI;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstIteratorAPI.GSTITERATOR_API;\n\n/**\n * Utility class for working with gstiterator.\n */\nclass GstIterator {\n    \n    static <T extends NativeObject> List<T> asList(GstIteratorPtr iter, Class<T> type) {\n        final GType gtype = GstTypes.typeFor(type);\n        final GValueAPI.GValue gValue = new GValueAPI.GValue(gtype);\n        List<T> list = new ArrayList<>();\n        while (GSTITERATOR_API.gst_iterator_next(iter, gValue) == 1) {\n            list.add((T) gValue.getValue());\n        }\n        gValue.reset();\n        GSTITERATOR_API.gst_iterator_free(iter);\n        return list;\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/GstObject.java",
    "content": "/* \n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wtay@chello.be>\n *                    2005 Wim Taymans <wim@fluendo.com>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport com.sun.jna.Pointer;\nimport java.util.logging.Logger;\nimport org.freedesktop.gstreamer.glib.GObject;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GObjectAPI;\nimport org.freedesktop.gstreamer.lowlevel.GType;\nimport org.freedesktop.gstreamer.lowlevel.GstControlBindingPtr;\nimport org.freedesktop.gstreamer.lowlevel.GstObjectPtr;\nimport org.freedesktop.gstreamer.lowlevel.GValueAPI.GValue;\n\nimport static org.freedesktop.gstreamer.lowlevel.GObjectAPI.GOBJECT_API;\nimport static org.freedesktop.gstreamer.lowlevel.GValueAPI.GVALUE_API;\nimport static org.freedesktop.gstreamer.lowlevel.GlibAPI.GLIB_API;\nimport static org.freedesktop.gstreamer.lowlevel.GstObjectAPI.GSTOBJECT_API;\nimport static org.freedesktop.gstreamer.lowlevel.GstValueAPI.GSTVALUE_API;\n\n/**\n * Base class for the GStreamer object hierarchy\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstObject.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstObject.html</a>\n * <p>\n * GstObject provides a root for the object hierarchy tree filed in by the\n * GStreamer library. It is currently a thin wrapper on top of {@link GObject}.\n * It is an abstract class that is not very usable on its own.\n *\n */\npublic class GstObject extends GObject {\n\n    private static Logger LOG = Logger.getLogger(GstObject.class.getName());\n\n    private final Handle handle;\n\n    /**\n     * Wraps an underlying C GstObject with a Java proxy\n     *\n     * @param init Initialization data\n     */\n    protected GstObject(Initializer init) {\n        this(new Handle(init.ptr.as(GstObjectPtr.class, GstObjectPtr::new), init.ownsHandle), init.needRef);\n    }\n\n    protected GstObject(Handle handle, boolean needRef) {\n        super(handle, needRef);\n        this.handle = handle;\n    }\n\n    /**\n     * Set the value of a GstObject property from a String representation.\n     * <p>\n     * The data value is deserialized using <code>gst_value_deserialize</code>.\n     *\n     * @param property the property to set\n     * @param data the value as a valid String representation\n     * @throws IllegalArgumentException if the data cannot be deserialized to\n     * the required type.\n     */\n    public void setAsString(String property, String data) {\n        GObjectAPI.GParamSpec propertySpec = findProperty(property);\n        if (propertySpec == null) {\n            throw new IllegalArgumentException(\"Unknown property: \" + property);\n        }\n        final GType propType = propertySpec.value_type;\n\n        GValue propValue = new GValue();\n        GVALUE_API.g_value_init(propValue, propType);\n\n        boolean success = GSTVALUE_API.gst_value_deserialize(propValue, data);\n\n        if (success) {\n            GOBJECT_API.g_param_value_validate(propertySpec, propValue);\n            GOBJECT_API.g_object_set_property(this, property, propValue);\n        }\n\n        GVALUE_API.g_value_unset(propValue); // Release any memory\n\n        if (!success) {\n            throw new IllegalArgumentException(\n                    \"Unable to deserialize data to required type: \"\n                            + propType.getTypeName());\n        }\n\n    }\n\n    /**\n     * Get the value of a GstObject property as a serialized String\n     * representation of its value.\n     * <p>\n     * The data value is serialized using <code>gst_value_serialize</code>.\n     *\n     * @param property the property to get\n     * @return serialized String value of property\n     */\n    public String getAsString(String property) {\n        GObjectAPI.GParamSpec propertySpec = findProperty(property);\n        if (propertySpec == null) {\n            throw new IllegalArgumentException(\"Unknown property: \" + property);\n        }\n        final GType propType = propertySpec.value_type;\n        GValue propValue = new GValue();\n        GVALUE_API.g_value_init(propValue, propType);\n        GOBJECT_API.g_object_get_property(this, property, propValue);\n        Pointer ptr = GSTVALUE_API.gst_value_serialize(propValue);\n        String ret = ptr.getString(0);\n        GLIB_API.g_free(ptr);\n        return ret;\n    }\n\n    private GObjectAPI.GParamSpec findProperty(String propertyName) {\n        Pointer ptr = GOBJECT_API.g_object_class_find_property(\n                getRawPointer().getPointer(0), propertyName);\n        if (ptr == null) {\n            return null;\n        }\n        return new GObjectAPI.GParamSpec(ptr);\n    }\n\n    /**\n     * Sets the name of this object, or gives this object a guaranteed unique\n     * name (if name is null).\n     *\n     * Returns: TRUE if the name could be set. Since Objects that have a parent\n     * cannot be renamed, this function returns FALSE in those cases.\n     *\n     * MT safe.\n     *\n     * @param name new name of object\n     * @return true if the name was set. Since Objects that have a parent cannot\n     * be renamed, this function returns false in those cases.\n     */\n    public boolean setName(String name) {\n        LOG.entering(\"GstObject\", \"setName\", name);\n        return GSTOBJECT_API.gst_object_set_name(this, name);\n    }\n\n    /**\n     * Returns a copy of the name of this object.\n     *\n     * For a nameless object, this returns null.\n     *\n     * @return the name of this object.\n     */\n    public String getName() {\n        LOG.entering(\"GstObject\", \"getName\");\n        return GSTOBJECT_API.gst_object_get_name(this);\n    }\n\n    /**\n     * Returns this object's parent, if there is one.\n     *\n     * @return parent or <code>null</code>\n     */\n    public GstObject getParent() {\n        return GSTOBJECT_API.gst_object_get_parent(this);\n    }\n\n    /**\n     * Returns a suggestion for timestamps where buffers should be split to get\n     * best controller results.\n     *\n     * @return the suggested timestamp or {@link ClockTime#NONE} if no\n     * control-rate was set.\n     */\n    public long suggestNextSync() {\n        return GSTOBJECT_API.gst_object_suggest_next_sync(handle.getPointer());\n    }\n\n    /**\n     * Sets the properties of the object, according to the {@link ControlSource}\n     * that (maybe) handle them and for the given timestamp.\n     * <p>\n     * If this function fails, it is most likely the application developers\n     * fault. Most probably the control sources are not setup correctly.\n     *\n     * @param timestamp the time that should be processed\n     * @return true if the controller values have been applied to the object\n     * properties\n     */\n    public boolean syncValues(long timestamp) {\n        return GSTOBJECT_API.gst_object_sync_values(handle.getPointer(), timestamp);\n    }\n\n    /**\n     * Check if this object has active controlled properties.\n     *\n     * @return TRUE if the object has active controlled properties\n     */\n    public boolean hasActiveControlBindings() {\n        return GSTOBJECT_API.gst_object_has_active_control_bindings(handle.getPointer());\n    }\n\n    /**\n     * This function is used to disable all controlled properties of the object\n     * for some time, i.e. {@link #syncValues(long) } will do nothing.\n     *\n     * @param disabled whether to disable the controllers or not\n     */\n    public void setControlBindingsDisabled(boolean disabled) {\n        GSTOBJECT_API.gst_object_set_control_bindings_disabled(handle.getPointer(), disabled);\n    }\n\n    /**\n     * This function is used to disable the control bindings on a property for\n     * some time, i.e. {@link #syncValues(long) } will do nothing for the\n     * property.\n     *\n     * @param propertyName property to disable\n     * @param disabled whether to disable the controller or not\n     */\n    public void setControlBindingDisabled(String propertyName, boolean disabled) {\n        GSTOBJECT_API.gst_object_set_control_binding_disabled(handle.getPointer(), propertyName, disabled);\n    }\n\n    /**\n     * Attach a {@link ControlBinding } to this object. If there was already a\n     * binding for this property it will be replaced.\n     *\n     * @param binding the ControlBinding that should be used\n     * @throws IllegalStateException if the binding has not been setup for this\n     * object\n     */\n    public void addControlBinding(ControlBinding binding) {\n        GstControlBindingPtr bindingPtr = Natives.getPointer(binding)\n                .as(GstControlBindingPtr.class, GstControlBindingPtr::new);\n        boolean ok = GSTOBJECT_API.gst_object_add_control_binding(handle.getPointer(), bindingPtr);\n        if (!ok) {\n            throw new IllegalStateException();\n        }\n    }\n\n    /**\n     * Gets the corresponding {@link ControlBinding} for the property.\n     *\n     * @param propertyName name of the property\n     * @return control binding for the property or NULL if the property is not\n     * controlled\n     */\n    public ControlBinding getControlBinding(String propertyName) {\n        GstControlBindingPtr ptr = GSTOBJECT_API.gst_object_get_control_binding(\n                handle.getPointer(), propertyName);\n        return ptr == null ? null : Natives.callerOwnsReturn(ptr, ControlBinding.class);\n    }\n\n    /**\n     * Removes the corresponding {@link ControlBinding }.\n     *\n     * @param binding the binding to remove\n     * @return true if the binding could be removed\n     */\n    public boolean removeControlBinding(ControlBinding binding) {\n        GstControlBindingPtr bindingPtr = Natives.getPointer(binding)\n                .as(GstControlBindingPtr.class, GstControlBindingPtr::new);\n        return GSTOBJECT_API.gst_object_remove_control_binding(handle.getPointer(), bindingPtr);\n    }\n\n    @Override\n    public String toString() {\n        return String.format(\"%s: [%s]\", getClass().getSimpleName(), getName());\n    }\n//    protected static Initializer initializer(Pointer ptr) {\n//        return initializer(ptr, true, true);\n//    }\n//    \n//    protected static Initializer initializer(Pointer ptr, boolean needRef) {\n//        return initializer(ptr, needRef, true);\n//    }\n\n    protected static class Handle extends GObject.Handle {\n\n        public Handle(GstObjectPtr ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n\n        @Override\n        protected void ref() {\n            GSTOBJECT_API.gst_object_ref(getPointer());\n        }\n\n        @Override\n        protected void sink() {\n            GSTOBJECT_API.gst_object_ref_sink(getPointer());\n        }\n\n        @Override\n        protected void unref() {\n            GSTOBJECT_API.gst_object_unref(getPointer());\n        }\n\n        @Override\n        protected GstObjectPtr getPointer() {\n            return (GstObjectPtr) super.getPointer();\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/Meta.java",
    "content": "/*\n * Copyright (c) 2020 Neil C Smith\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport java.util.Objects;\nimport org.freedesktop.gstreamer.glib.NativeObject;\nimport org.freedesktop.gstreamer.lowlevel.GPointer;\nimport org.freedesktop.gstreamer.lowlevel.GType;\nimport org.freedesktop.gstreamer.lowlevel.GstMetaPtr;\n\n/**\n * Base for all metadata types added to a Buffer.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/documentation/gstreamer/gstmeta.html\"\n * >https://gstreamer.freedesktop.org/documentation/gstreamer/gstmeta.html</a>\n * <p>\n */\npublic class Meta extends NativeObject {\n\n    /**\n     * Create Meta from Initializer.\n     *\n     * @param init initializer.\n     */\n    protected Meta(Initializer init) {\n        this(new Handle(init.ptr.as(GstMetaPtr.class, GstMetaPtr::new),\n                init.ownsHandle));\n    }\n\n    /**\n     * Create Meta from Handle.\n     *\n     * @param handle native object handle.\n     */\n    protected Meta(Handle handle) {\n        super(handle);\n    }\n\n    @Override\n    public String toString() {\n        GstMetaPtr pointer = (GstMetaPtr)this.getPointer();\n        return \"[meta : gType=\" + pointer.getGType() + \"]\";\n    }\n\n    /**\n     * NativeObject.Handle implementation.\n     */\n    protected static class Handle extends NativeObject.Handle {\n\n        /**\n         * Create Handle.\n         *\n         * @param ptr pointer to underlying native GstMeta.\n         * @param ownsHandle\n         */\n        public Handle(GstMetaPtr ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n\n        @Override\n        protected void disposeNativeHandle(GPointer ptr) {\n        }\n\n    }\n\n    /**\n     * API for Meta subclass. Used for querying from Buffer.\n     * <p>\n     * The relevant API will usually be available as a public static final field\n     * on the implementation class.\n     * <p>\n     * The API type reflects two distinct types (api and implementation) used in\n     * the underlying GStreamer GstMetaInfo.\n     * <p>\n     * See upstream documentation at\n     * <a href=\"https://gstreamer.freedesktop.org/documentation/gstreamer/gstmeta.html#GstMetaInfo\"\n     * >https://gstreamer.freedesktop.org/documentation/gstreamer/gstmeta.html#GstMetaInfo</a>\n     * <p>\n     *\n     * @param <T> implementation type\n     */\n    public static final class API<T extends Meta> {\n\n        private final Class<T> implClass;\n        private final String apiTypeName;\n\n        private GType apiType;\n\n        /**\n         * Create an API for the given implementation type.\n         *\n         * @param impl class implementing the API, must be registered to the\n         * underlying implementation GType\n         * @param api name of the underlying API GType\n         */\n        public API(Class<T> impl, String api) {\n            this.implClass = Objects.requireNonNull(impl);\n            this.apiTypeName = Objects.requireNonNull(api);\n            apiType = GType.INVALID;\n        }\n\n        Class<T> getImplClass() {\n            return implClass;\n        }\n\n        GType getAPIGType() {\n            GType type = apiType;\n            if (type == GType.INVALID) {\n                type = GType.valueOf(apiTypeName);\n                apiType = type;\n            }\n            return type;\n        }\n\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/MetaFlags.java",
    "content": "/*\n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2020 Petr Lastovka\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.NativeFlags;\n\n /**\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/documentation/gstreamer/gstmeta.html#GstMetaFlags\"\n * >https://gstreamer.freedesktop.org/documentation/gstreamer/gstmeta.html#GstMetaFlags</a>\n */\n/*public*/ enum MetaFlags implements NativeFlags<MetaFlags> {\n\n//    /**\n//     * no flags\n//     */\n//    GST_META_FLAG_NONE(0),\n    /**\n     * metadata should not be modified\n     */\n    GST_META_FLAG_READONLY(1 << 0),\n    /**\n     * metadata is managed by a bufferpool\n     */\n    GST_META_FLAG_POOLED(1 << 1),\n    /**\n     * metadata should not be removed\n     */\n    GST_META_FLAG_LOCKED(1 << 2),\n//    /**\n//     * additional flags can be added starting from this flag.\n//     */\n//    GST_META_FLAG_LAST(1 << 16)\n//    \n    ;\n\n    private final int value;\n\n    MetaFlags(int value) {\n        this.value = value;\n    }\n\n    /**\n     * Gets the integer value of the enum.\n     *\n     * @return The integer value for this enum.\n     */\n    @Override\n    public int intValue() {\n        return value;\n    }\n\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/MiniObject.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2016 Christophe Lafolet\n * Copyright (c) 2014 Tom Greenwood <tgreenwood@cafex.com>\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007 Wayne Meissner\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.lowlevel.GstMiniObjectAPI.MiniObjectStruct;\nimport org.freedesktop.gstreamer.glib.RefCountedObject;\nimport org.freedesktop.gstreamer.lowlevel.GPointer;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstMiniObjectAPI.GSTMINIOBJECT_API;\nimport org.freedesktop.gstreamer.lowlevel.GstMiniObjectPtr;\n\n/**\n * Lightweight base class for the GStreamer object hierarchy\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/gstreamer-GstMiniObject.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/gstreamer-GstMiniObject.html</a>\n * <p>\n * MiniObject is a simple structure that can be used to implement refcounted\n * types.\n */\npublic abstract class MiniObject extends RefCountedObject {\n\n    /**\n     * Creates a new instance of MiniObject\n     */\n    protected MiniObject(Initializer init) {\n        this(new Handle(init.ptr.as(GstMiniObjectPtr.class, GstMiniObjectPtr::new),\n                init.ownsHandle), init.needRef);\n    }\n    \n    protected MiniObject(Handle handle, boolean needRef) {\n        super(handle, needRef);\n    }\n\n    /**\n     * If mini_object has the LOCKABLE flag set, check if the current EXCLUSIVE\n     * lock on object is the only one, this means that changes to the object\n     * will not be visible to any other object.\n     *\n     * <p>\n     * </p>If the LOCKABLE flag is not set, check if the refcount of mini_object\n     * is exactly 1, meaning that no other reference exists to the object and\n     * that the object is therefore writable.\n     *\n     * <p>\n     * </p>Modification of a mini-object should only be done after verifying\n     * that it is writable.\n     *\n     * @return true if the object is writable.\n     */\n    public boolean isWritable() {\n        return GSTMINIOBJECT_API.gst_mini_object_is_writable(this);\n    }\n\n    /**\n     * Makes a writable instance of this MiniObject.\n     * <p>\n     * The result is cast to <tt>subclass</tt>.\n     *\n     * @return a writable version (possibly a duplicate) of this MiniObject.\n     */\n    protected <T extends MiniObject> T makeWritable() {\n        MiniObject result = GSTMINIOBJECT_API.gst_mini_object_make_writable(this);\n        if (result == null) {\n            throw new NullPointerException(\"Could not make \" + this.getClass().getSimpleName() + \" writable\");\n        }\n        return (T) result;\n    }\n\n    /**\n     * Create a new MiniObject as a copy of the this instance.\n     *\n     * @return the new MiniObject.\n     */\n    public <T extends MiniObject> T copy() {\n        MiniObject result = GSTMINIOBJECT_API.gst_mini_object_copy(this);\n        if (result == null) {\n            throw new NullPointerException(\"Could not make a copy of \" + this.getClass().getSimpleName());\n        }\n        return (T) result;\n    }\n\n    public int getRefCount() {\n        final MiniObjectStruct struct = new MiniObjectStruct(getRawPointer());\n        return (Integer) struct.readField(\"refcount\");\n    }\n\n    protected static class Handle extends RefCountedObject.Handle {\n\n        public Handle(GstMiniObjectPtr ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n\n        @Override\n        protected void disposeNativeHandle(GPointer ptr) {\n            GSTMINIOBJECT_API.gst_mini_object_unref(\n                    ptr.as(GstMiniObjectPtr.class, GstMiniObjectPtr::new));\n        }\n\n        @Override\n        protected void ref() {\n            GSTMINIOBJECT_API.gst_mini_object_ref(getPointer());\n        }\n\n        @Override\n        protected void unref() {\n            GSTMINIOBJECT_API.gst_mini_object_unref(getPointer());\n        }\n\n        @Override\n        protected GstMiniObjectPtr getPointer() {\n            return (GstMiniObjectPtr) super.getPointer();\n        }\n\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/MiniObjectFlags.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.NativeFlags;\n\n/**\n * Flags for {@link MiniObject }\n */\npublic enum MiniObjectFlags implements NativeFlags<MiniObjectFlags> {\n    /**\n     * the object can be locked and unlocked with gst_mini_object_lock() and\n     * gst_mini_object_unlock()\n     *\n     */\n    LOCKABLE(1 << 0),\n    /**\n     * the object is permanently locked in READONLY mode. Only read locks can be\n     * performed on the object.\n     */\n    LOCK_READONLY(1 << 1),\n    /**\n     * the object is expected to stay alive even after gst_deinit() has been\n     * called and so should be ignored by leak detection tools. (Since 1.10)\n     */\n    MAY_BE_LEAKED(1 << 2),\n    /**\n     * The last valid MiniObject flag\n     */\n    LAST(1 << 4);\n\n    private final int value;\n    \n    private MiniObjectFlags(int value) {\n        this.value = value;\n    }\n\n    public int intValue() {\n        return value;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/Pad.java",
    "content": "/* \n * Copyright (C) 2020 Neil C Smith\n * Copyright (C) 2018 Antonio Morales\n * Copyright (C) 2014 Tom Greenwood <tgreenwood@cafex.com>\n * Copyright (C) 2009 Tamas Korodi <kotyo@zamba.fm>\n * Copyright (C) 2007 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wtay@chello.be>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport com.sun.jna.NativeLong;\nimport org.freedesktop.gstreamer.event.Event;\nimport com.sun.jna.Pointer;\nimport java.util.HashSet;\nimport java.util.Set;\nimport org.freedesktop.gstreamer.glib.NativeFlags;\nimport org.freedesktop.gstreamer.glib.Natives;\n\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback;\nimport org.freedesktop.gstreamer.lowlevel.GstPadProbeInfo;\nimport org.freedesktop.gstreamer.lowlevel.GstPadAPI;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstPadAPI.GSTPAD_API;\nimport org.freedesktop.gstreamer.lowlevel.GstPadPtr;\n\n/**\n * Object contained by elements that allows links to other elements.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPad.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPad.html</a>\n * <p>\n * An {@link Element} is linked to other elements via \"pads\", which are extremely\n * light-weight generic link points. After two pads are retrieved from an\n * element with {@link Element#getPad}, the pads can be link with {@link #link}.\n * (For quick links, you can also use {@link Element#link}, which will make the\n * obvious link for you if it's straightforward.)\n * <p>\n * Pads are typically created from a {@link PadTemplate} with\n * {@link #Pad(PadTemplate, String)}.\n * <p>\n * Pads have {@link Caps} attached to it to describe the media type they are\n * capable of dealing with. {@link #queryCaps} and {@link #setCaps} are used to\n * manipulate the caps of the pads. Pads created from a pad template cannot set\n * capabilities that are incompatible with the pad template capabilities.\n * <p>\n * Pads without pad templates can be created with gst_pad_new(), which takes a\n * direction and a name as an argument. If the name is NULL, then a guaranteed\n * unique name will be assigned to it.\n * <p>\n * {@link #getParentElement} will retrieve the Element that owns the pad.\n * <p>\n * An Element creating a pad will typically use the various\n * gst_pad_set_*_function() calls to register callbacks for various events on\n * the pads.\n * <p>\n * GstElements will use gst_pad_push() and gst_pad_pull_range() to push out or\n * pull in a buffer.\n * <p>\n * To send an Event on a pad, use {@link #sendEvent} and {@link #pushEvent}.\n *\n * @see PadTemplate\n * @see Element\n * @see Event\n */\npublic class Pad extends GstObject {\n\n    public static final String GTYPE_NAME = \"GstPad\";\n\n    private static final int EVENT_HAS_INFO_MASK = GstPadAPI.GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GstPadAPI.GST_PAD_PROBE_TYPE_EVENT_UPSTREAM;\n    private final Handle handle;\n\n    /**\n     * Creates a new instance of Pad\n     */\n    Pad(Initializer init) {\n        this(new Handle(init.ptr.as(GstPadPtr.class, GstPadPtr::new), init.ownsHandle), init.needRef);\n    }\n\n    private Pad(Handle handle, boolean needRef) {\n        super(handle, needRef);\n        this.handle = handle;\n    }\n\n    /**\n     * Creates a new pad with the given name in the given direction. If name is\n     * null, a guaranteed unique name (across all pads) will be assigned.\n     *\n     * @param name The name of the new pad.\n     * @param direction The direction of the new pad.\n     */\n    public Pad(String name, PadDirection direction) {\n        this(Natives.initializer(GSTPAD_API.ptr_gst_pad_new(name, direction), false));\n    }\n\n    /**\n     * Creates a new pad with the given name from the given template.\n     *\n     * If name is null, a guaranteed unique name (across all pads) will be\n     * assigned.\n     *\n     * @param template The pad template to use.\n     * @param name The name of the new pad.\n     */\n    public Pad(PadTemplate template, String name) {\n        this(Natives.initializer(GSTPAD_API.ptr_gst_pad_new_from_template(template, name), false));\n    }\n\n    /**\n     * Gets the capabilities this pad can produce or consume. Note that this\n     * method doesn't necessarily return the caps set by sending a\n     * gst_event_new_caps() - use {@link #getCurrentCaps() } for that instead.\n     * queryCaps returns all possible caps a pad can operate with,\n     * using the pad's CAPS query function, If the query fails, this function\n     * will return filter, if not NULL, otherwise ANY.\n     * <p>\n     * When called on sinkpads filter contains the caps that upstream could\n     * produce in the order preferred by upstream. When called on srcpads filter\n     * contains the caps accepted by downstream in the preferred order. filter\n     * might be NULL but if it is not NULL the returned caps will be a subset of\n     * filter .\n     * <p>\n     * Note that this function does not return writable Caps.\n     *\n     * @param filter suggested Caps or null\n     * @return a newly allocated copy of the {@link Caps} of this pad.\n     */\n    public Caps queryCaps(Caps filter) {\n        return GSTPAD_API.gst_pad_query_caps(this, filter);\n    }\n\n    /**\n     * Gets the capabilities of the allowed media types that can flow through\n     * this pad and its peer.\n     * <p>\n     * The allowed capabilities is calculated as the intersection of the results\n     * of calling {@link #queryCaps} on this pad and its peer.\n     * <p>\n     * MT safe.\n     *\n     * @return The allowed {@link Caps} of the pad link, or null if this pad has\n     * no peer.\n     */\n    public Caps getAllowedCaps() {\n        return GSTPAD_API.gst_pad_get_allowed_caps(this);\n    }\n\n    /**\n     * Gets the capabilities currently configured on pad with the last\n     * GST_EVENT_CAPS event.\n     *\n     * @return the negotiated #GstCaps or null if this pad has\n     * no current caps\n     *\n     */\n    public Caps getCurrentCaps() {\n        return GSTPAD_API.gst_pad_get_current_caps(this);\n    }\n\n    /**\n     * Get the peer of this pad.\n     *\n     * MT safe.\n     *\n     * @return The peer Pad of this Pad.\n     */\n    public Pad getPeer() {\n        return GSTPAD_API.gst_pad_get_peer(this);\n    }\n\n    /**\n     * Get the capabilities of the peer connected to this pad.\n     *<p>\n     * When called on srcpads filter contains the caps that upstream could\n     * produce in the order preferred by upstream. When called on sinkpads\n     * filter contains the caps accepted by downstream in the preferred order.\n     * filter might be NULL but if it is not NULL the returned caps will be a\n     * subset of filter .\n     *\n     * @param filter Caps to filter by, or null\n     * @return the {@link Caps} of the peer pad, or null if there is no peer\n     * pad.\n     */\n    public Caps peerQueryCaps(Caps filter) {\n        return GSTPAD_API.gst_pad_peer_query_caps(this, filter);\n    }\n\n    /**\n     * Check if the pad accepts the given caps.\n     *\n     * @param caps a {@link Caps} to check on the pad.\n     * @return true if the pad can accept the caps.\n     */\n    public boolean queryAcceptCaps(Caps caps) {\n        return GSTPAD_API.gst_pad_query_accept_caps(this, caps);\n    }\n\n    /**\n     * Check if the peer of this pad accepts the caps. If this pad has no peer,\n     * this method returns true.\n     *\n     * @param caps {@link Caps} to check on the pad\n     * @return true if the peer pad can accept the caps or this pad no peer.\n     */\n    public boolean peerQueryAcceptCaps(Caps caps) {\n        return GSTPAD_API.gst_pad_peer_query_accept_caps(this, caps);\n    }\n\n    /**\n     * Links this source pad and a sink pad.\n     *\n     * MT Safe.\n     *\n     * @param sink the sink Pad to link.\n     * @throws PadLinkException if pads cannot be linked.\n     */\n    public void link(Pad sink) throws PadLinkException {\n        PadLinkReturn result = GSTPAD_API.gst_pad_link(this, sink);\n        if (result != PadLinkReturn.OK) {\n            throw new PadLinkException(result);\n        }\n    }\n\n    /**\n     *\n     * Unlinks the source pad from the sink pad. Will emit the \"unlinked\" signal\n     * on both pads.\n     *\n     * MT safe.\n     *\n     * @param pad the sink Pad to unlink.\n     * @return true if the pads were unlinked. This function returns false if\n     * the pads were not linked together.\n     */\n    public boolean unlink(Pad pad) {\n        return GSTPAD_API.gst_pad_unlink(this, pad);\n    }\n\n    /**\n     * Check if this pad is linked to another pad or not.\n     *\n     * @return true if the pad is linked, else false.\n     */\n    public boolean isLinked() {\n        return GSTPAD_API.gst_pad_is_linked(this);\n    }\n\n    /**\n     * Get the direction of the pad. The direction of the pad is decided at\n     * construction time so this function does not take the LOCK.\n     *\n     * @return The {@link PadDirection} of the pad.\n     */\n    public PadDirection getDirection() {\n        return GSTPAD_API.gst_pad_get_direction(this);\n    }\n\n    /**\n     * Get the parent of this pad, cast to an {@link Element}. If this pad has no\n     * parent or its parent is not an element, returns null.\n     *\n     * @return The parent of the pad.\n     */\n    public Element getParentElement() {\n        return GSTPAD_API.gst_pad_get_parent_element(this);\n    }\n\n    /**\n     * Activates or deactivates the given pad. Normally called from within core\n     * state change functions.\n     * <p>\n     * If active is true, makes sure the pad is active. If it is already active,\n     * either in push or pull mode, just return. Otherwise dispatches to the\n     * pad's activate function to perform the actual activation.\n     * <p>\n     * If not @active, checks the pad's current mode and calls\n     * gst_pad_activate_push() or gst_pad_activate_pull(), as appropriate, with\n     * a FALSE argument.\n     *\n     * @param active whether or not the pad should be active.\n     * @return true if the operation was successful.\n     */\n    public boolean setActive(boolean active) {\n        return GSTPAD_API.gst_pad_set_active(this, active);\n    }\n\n    /**\n     * Checks if the pad is blocked or not. This function returns the last\n     * requested state of the pad. It is not certain that the pad is actually\n     * blocking at this point (see {@link #isBlocking}).\n     *\n     * @return true if the pad is blocked.\n     */\n    public boolean isBlocked() {\n        return GSTPAD_API.gst_pad_is_blocked(this);\n    }\n\n    /**\n     * Run a runnable under a blocked state\n     *\n     * @param callback The code to run when pad is blocked\n     */\n    public void block(final Runnable callback) {\n        addEventProbe(new EVENT_PROBE() {\n            public PadProbeReturn eventReceived(Pad pad, Event event) {\n                callback.run();\n                pad.removeCallback(EVENT_PROBE.class, this);\n                return PadProbeReturn.REMOVE;\n            }\n        }, GstPadAPI.GST_PAD_PROBE_TYPE_IDLE);\n    }\n\n    /**\n     * Checks if the pad is blocking or not. This is a guaranteed state of\n     * whether the pad is actually blocking on a {@link Buffer} or an\n     * {@link Event}.\n     *\n     * @return true if the pad is blocking.\n     */\n    public boolean isBlocking() {\n        return GSTPAD_API.gst_pad_is_blocking(this);\n    }\n\n    /**\n     * Add a listener for the <code>linked</code> signal on this {@link Pad}\n     *\n     * @param listener The listener to be called when a peer {@link Pad} is\n     * linked.\n     */\n    public void connect(final LINKED listener) {\n        connect(LINKED.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public boolean callback(Pad pad, Pad peer) {\n                listener.linked(pad, peer);\n                return true;\n            }\n        });\n    }\n\n    /**\n     * Remove a listener for the <code>linked</code> signal on this {@link Pad}\n     *\n     * @param listener The listener previously added for this signal.\n     */\n    public void disconnect(LINKED listener) {\n        disconnect(LINKED.class, listener);\n    }\n\n    /**\n     * Add a listener for the <code>unlinked</code> signal on this {@link Pad}\n     *\n     * @param listener The listener to be called when when a peer {@link Pad} is\n     * unlinked.\n     */\n    public void connect(final UNLINKED listener) {\n        connect(UNLINKED.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public boolean callback(Pad pad, Pad peer) {\n                listener.unlinked(pad, peer);\n                return true;\n            }\n        });\n    }\n\n    /**\n     * Remove a listener for the <code>unlinked</code> signal on this\n     * {@link Pad}\n     *\n     * @param listener The listener previously added for this signal.\n     */\n    public void disconnect(UNLINKED listener) {\n        disconnect(UNLINKED.class, listener);\n    }\n\n    /**\n     * Be notified of different states of pads. The provided callback is called\n     * for every state that matches mask.\n     * <p>\n     * Probes are called in groups: First {@link PadProbeType#BLOCK} probes are\n     * called, then others, then finally {@link PadProbeType#IDLE}. The only\n     * exception here are IDLE probes that are called immediately if the pad is\n     * already idle while calling addProbe(). In each of the groups, probes are\n     * called in the order in which they were added.\n     *\n     * @param mask set of mask flags for probe - common options are fields of\n     * {@link PadProbeType}\n     * @param callback callback that will be called with notifications of the\n     * pad state\n     */\n    public void addProbe(final Set<PadProbeType> mask, PROBE callback) {\n        addProbe(NativeFlags.toInt(mask), callback);\n    }\n    \n    /**\n     * Be notified of different states of pads. The provided callback is called\n     * for every state that matches mask.\n     * <p>\n     * Probes are called in groups: First {@link PadProbeType#BLOCK} probes are\n     * called, then others, then finally {@link PadProbeType#IDLE}. The only\n     * exception here are IDLE probes that are called immediately if the pad is\n     * already idle while calling addProbe(). In each of the groups, probes are\n     * called in the order in which they were added.\n     *\n     * @param mask mask flag for probe\n     * @param callback callback that will be called with notifications of the\n     * pad state\n     */\n    public void addProbe(PadProbeType mask, PROBE callback) {\n        addProbe(mask.intValue(), callback);\n    }\n    \n    synchronized void addProbe(int mask, PROBE callback) {\n        final GstPadAPI.PadProbeCallback probe = new GstPadAPI.PadProbeCallback() {\n            @Override\n            public PadProbeReturn callback(Pad pad, GstPadProbeInfo probeInfo, Pointer user_data) {\n                PadProbeInfo info = new PadProbeInfo(probeInfo);\n                PadProbeReturn ret = callback.probeCallback(pad, info);\n                info.invalidate();\n                if (ret == PadProbeReturn.REMOVE) {\n                    // don't want handle to try and remove in GCallback::disconnect\n                    // @TODO move to Map<PROBE, NativeLong> of probes over callback\n                    handle.probes.remove(probeInfo.id);\n                    removeCallback(PROBE.class, callback);\n                }\n                return ret;\n            }\n        };\n\n        NativeLong id = handle.addProbe(mask, probe);\n        if (id.longValue() == 0) {\n            // the Probe was an IDLE-Probe and it was already handled synchronously in handle.addProbe,\n            // so no Callback needs to be registered\n            return;\n        }\n\n        GCallback cb = new GCallback(id, probe) {\n            @Override\n            protected void disconnect() {\n                handle.removeProbe(id);\n            }\n        };\n        addCallback(PROBE.class, callback, cb);\n    }\n    \n    /**\n     * Remove the provided probe callback from the Pad.\n     * \n     * @param callback callback to remove\n     */\n    public synchronized void removeProbe(PROBE callback) {\n        removeCallback(PROBE.class, callback);\n    }\n\n    public void addEventProbe(final EVENT_PROBE listener) {\n        final int mask = GstPadAPI.GST_PAD_PROBE_TYPE_EVENT_BOTH | GstPadAPI.GST_PAD_PROBE_TYPE_EVENT_FLUSH;\n        addEventProbe(listener, mask);\n    }\n\n    synchronized void addEventProbe(final EVENT_PROBE listener, final int mask) {\n        final GstPadAPI.PadProbeCallback probe = new GstPadAPI.PadProbeCallback() {\n            public PadProbeReturn callback(Pad pad, GstPadProbeInfo probeInfo, Pointer user_data) {\n                if ((probeInfo.padProbeType & mask) != 0) {\n                    Event event = null;\n                    if ((probeInfo.padProbeType & EVENT_HAS_INFO_MASK) != 0) {\n                        event = GSTPAD_API.gst_pad_probe_info_get_event(probeInfo);\n                    }\n                    PadProbeReturn ret = listener.eventReceived(pad, event);\n                    if (ret == PadProbeReturn.REMOVE) {\n                        // don't want handle to try and remove in GCallback::disconnect\n                        handle.probes.remove(probeInfo.id);\n                        removeCallback(EVENT_PROBE.class, listener);\n                    }\n                    return ret;\n                }\n\n                return PadProbeReturn.OK;\n            }\n        };\n\n        NativeLong id = handle.addProbe(mask, probe);\n        if (id.longValue() == 0) {\n            // the Probe was an IDLE-Probe and it was already handled synchronously in handle.addProbe,\n            // so no Callback needs to be registered\n            return;\n        }\n\n        GCallback cb = new GCallback(id, probe) {\n            @Override\n            protected void disconnect() {\n                handle.removeProbe(id);\n            }\n        };\n        addCallback(EVENT_PROBE.class, listener, cb);\n    }\n\n    public void removeEventProbe(EVENT_PROBE listener) {\n        removeCallback(EVENT_PROBE.class, listener);\n    }\n\n    public synchronized void addDataProbe(final DATA_PROBE listener) {\n\n        final GstPadAPI.PadProbeCallback probe = new GstPadAPI.PadProbeCallback() {\n            public PadProbeReturn callback(Pad pad, GstPadProbeInfo probeInfo, Pointer user_data) {\n                if ((probeInfo.padProbeType & GstPadAPI.GST_PAD_PROBE_TYPE_BUFFER) != 0) {\n                    Buffer buffer = GSTPAD_API.gst_pad_probe_info_get_buffer(probeInfo);\n                    PadProbeReturn ret = listener.dataReceived(pad, buffer);\n                    if (ret == PadProbeReturn.REMOVE) {\n                        // don't want handle to try and remove in GCallback::disconnect\n                        handle.probes.remove(probeInfo.id);\n                        removeCallback(DATA_PROBE.class, listener);\n                    }\n                    return ret;\n                }\n\n                return PadProbeReturn.OK;\n            }\n        };\n\n        GCallback cb = new GCallback(handle.addProbe(GstPadAPI.GST_PAD_PROBE_TYPE_BUFFER, probe), probe) {\n            @Override\n            protected void disconnect() {\n                handle.removeProbe(id);\n            }\n        };\n\n        addCallback(DATA_PROBE.class, listener, cb);\n    }\n\n    public void removeDataProbe(DATA_PROBE listener) {\n        removeCallback(DATA_PROBE.class, listener);\n    }\n\n    /**\n     * Sends the event to this pad.\n     * <p>\n     * This function can be used by applications to send events in the pipeline.\n     *\n     * <p>\n     * If this pad is a source pad, <tt>event</tt> should be an upstream event.\n     * If this pad is a sink pad, <tt>event<tt> should be a downstream event.\n     * <p>\n     * For example, you would not send a {@link EventType#EOS} on a src pad; EOS\n     * events only propagate downstream.\n     *\n     * <p>\n     * Furthermore, some downstream events have to be serialized with data flow,\n     * like EOS, while some can travel out-of-band, like\n     * {@link EventType#FLUSH_START}. If the event needs to be serialized with\n     * data flow, this function will take the pad's stream lock while calling\n     * its event function.\n     *\n     * @param event the event to send.\n     * @return <tt>true</tt> if the event was handled.\n     */\n    public boolean sendEvent(Event event) {\n        return GSTPAD_API.gst_pad_send_event(this, event);\n    }\n\n    /**\n     * Sends the event to the peer of this pad.\n     *\n     * <p>\n     * This function is mainly used by elements to send events to their peer\n     * elements.\n     *\n     * @param event the event to send\n     * @return true if the event was handled\n     */\n    public boolean pushEvent(Event event) {\n        return GSTPAD_API.gst_pad_push_event(this, event);\n    }\n\n    /**\n     * Chain a buffer to pad.\n     * <p>\n     * The function returns {@link FlowReturn#FLUSHING} if the\n     * pad was flushing.\n     * <p>\n     * If the caps on buffer are different from the current caps on pad, this\n     * function will call any function installed on pad (see\n     * gst_pad_set_setcaps_function()). If the new caps are not acceptable for\n     * pad, this function returns\n     * {@link FlowReturn#NOT_NEGOTIATED}.\n     * <p>\n     * The function proceeds calling the chain function installed on pad and the\n     * return value of that function is returned to the caller.\n     * {@link FlowReturn#NOT_SUPPORTED} is returned if pad has no\n     * chain function.\n     * <p>\n     * In all cases, success or failure, the caller loses its reference to\n     * buffer after calling this function.\n     *\n     * @param buffer the Buffer, returns {@link FlowReturn#ERROR}\n     * if NULL.\n     * @return a org.gstreamer.FlowReturn\n     */\n    public FlowReturn chain(Buffer buffer) {\n        return GSTPAD_API.gst_pad_chain(this, buffer);\n    }\n\n    /**\n     * When pad is flushing this function returns\n     * {@link FlowReturn#FLUSHING} immediately.\n     * <p>\n     * Calls the getRange function of pad, see GstPadGetRangeFunction for a\n     * description of a getRange function. If pad has no getRange function\n     * installed (see gst_pad_set_getrange_function()) this function returns\n     * {@link FlowReturn#NOT_SUPPORTED}.\n     * <p>\n     * This is a lowlevel function. Usualy {@link Pad#pullRange} is used.\n     *\n     * @param offset The start offset of the buffer\n     * @param size The length of the buffer\n     * @param buffer the Buffer, returns {@link FlowReturn#ERROR} if NULL.\n     * @return a FlowReturn from the peer pad. When this function returns OK,\n     * buffer will contain a valid Buffer.\n     */\n    public FlowReturn getRange(long offset, int size, Buffer[] buffer) {\n        return GSTPAD_API.gst_pad_get_range(this, offset, size, buffer);\n    }\n\n    /**\n     * Pulls a buffer from the peer pad.\n     * <p>\n     * This function will first trigger the pad block signal if it was\n     * installed.\n     * <p>\n     * When pad is not linked {@link FlowReturn#NOT_LINKED} is returned else\n     * this function returns the result of {@link Pad#getRange} on the peer pad.\n     * See {@link Pad#getRange} for a list of return values and for the\n     * semantics of the arguments of this function.\n     * <p>\n     * buffer's caps must either be unset or the same as what is already\n     * configured on pad. Renegotiation within a running pull-mode pipeline is\n     * not supported.\n     *\n     * @param offset The start offset of the buffer\n     * @param size The length of the buffer\n     * @param buffer the Buffer, returns {@link FlowReturn#ERROR} if NULL.\n     * @return a FlowReturn from the peer pad. When this function returns OK,\n     * buffer will contain a valid Buffer. MT safe.\n     */\n    public FlowReturn pullRange(long offset, int size, Buffer[] buffer) {\n        return GSTPAD_API.gst_pad_pull_range(this, offset, size, buffer);\n    }\n\n    /**\n     * Pushes a buffer to the peer of pad . This function will call installed\n     * block probes before triggering any installed data probes.\n     * <p>\n     * The function proceeds calling gst_pad_chain() on the peer pad and returns\n     * the value from that function. If pad has no peer, {@link FlowReturn#NOT_LINKED}\n     * will be returned.\n     * <p>\n     * In all cases, success or failure, the caller loses its reference to\n     * buffer after calling this function.\n     *\n     * @param buffer the GstBuffer to push returns GST_FLOW_ERROR if not.\n     * [transfer full]\n     * @return a GstFlowReturn from the peer pad.\n     *\n     * MT safe.\n     */\n    public FlowReturn push(final Buffer buffer) {\n        return GSTPAD_API.gst_pad_push(this, buffer);\n    }\n\n    /**\n     * Gets the template for pad.\n     *\n     * @return the GstPadTemplate from which this pad was instantiated, or NULL\n     * if this pad has no template.\n     */\n    public PadTemplate getTemplate() {\n        return GSTPAD_API.gst_pad_get_pad_template(this);\n    }\n\n    /**\n     * Check if the pad has caps set on it with a GST_EVENT_CAPS events\n     *\n     * @return true if the pad has caps set\n     */\n    public boolean hasCurrentCaps() {\n        return GSTPAD_API.gst_pad_has_current_caps(this);\n    }\n\n    /**\n     * Signal emitted when new this {@link Pad} is linked to another {@link Pad}\n     *\n     * @see #connect(LINKED)\n     * @see #disconnect(LINKED)\n     */\n    public static interface LINKED {\n\n        /**\n         * Called when a {@link Pad} is linked to another Pad.\n         *\n         * @param pad the pad that emitted the signal.\n         * @param peer the peer pad that has been connected.\n         */\n        public void linked(Pad pad, Pad peer);\n    }\n\n    /**\n     * Signal emitted when new this {@link Pad} is disconnected from a peer\n     * {@link Pad}\n     *\n     * @see #connect(UNLINKED)\n     * @see #disconnect(UNLINKED)\n     */\n    public static interface UNLINKED {\n\n        /**\n         * Called when a {@link Pad} is unlinked from another Pad.\n         *\n         * @param pad the pad that emitted the signal.\n         * @param peer the peer pad that has been connected.\n         */\n        public void unlinked(Pad pad, Pad peer);\n    }\n\n    /**\n     * Callback used by\n     * {@link #addProbe(java.util.EnumSet, org.freedesktop.gstreamer.Pad.PROBE)}\n     */\n    public static interface PROBE {\n\n        /**\n         * Callback used by\n         * {@link #addProbe(java.util.EnumSet, org.freedesktop.gstreamer.Pad.PROBE)}.\n         * Gets called to notify about the current blocking type.\n         * <p>\n         * <b>The PadProbeInfo and any Buffer, Event or Query referenced from\n         * it, is only valid for the duration of the callback.</b>\n         *\n         * @param pad Pad that is blocked\n         * @param info PadProbeInfo with access to underlying data\n         * @return PadProbeReturn value\n         */\n        public PadProbeReturn probeCallback(Pad pad, PadProbeInfo info);\n\n    }\n\n    /**\n     * Probe for listening when an event passes through this Pad.\n     *\n     * @see #addEventProbe(EVENT_PROBE)\n     * @see #removeEventProbe(EVENT_PROBE)\n     */\n    public static interface EVENT_PROBE {\n\n        public PadProbeReturn eventReceived(Pad pad, Event event);\n        \n    }\n\n    /**\n     * Probe for listening when new data is available on the Pad.\n     *\n     * @see #addDataProbe(DATA_PROBE)\n     * @see #removeDataProbe(DATA_PROBE)\n     */\n    public static interface DATA_PROBE {\n\n        public PadProbeReturn dataReceived(Pad pad, Buffer buffer);\n        \n    }\n\n    private static class Handle extends GstObject.Handle {\n\n        private final Set<NativeLong> probes;\n\n        private Handle(GstPadPtr ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n            probes = new HashSet<>();\n        }\n\n        @Override\n        protected GstPadPtr getPointer() {\n            return (GstPadPtr) super.getPointer();\n        }\n\n        private synchronized NativeLong addProbe(int mask, GstPadAPI.PadProbeCallback probe) {\n            NativeLong id = GSTPAD_API.gst_pad_add_probe(getPointer(), mask, probe, null, null);\n            if (id.longValue() != 0) {\n                probes.add(id);\n            }\n            return id;\n        }\n\n        private synchronized void removeProbe(NativeLong id) {\n            if (probes.remove(id)) {\n                GSTPAD_API.gst_pad_remove_probe(getPointer(), id);\n            }\n        }\n\n        private synchronized void clearProbes() {\n            probes.forEach(id -> GSTPAD_API.gst_pad_remove_probe(getPointer(), id));\n            probes.clear();\n        }\n\n        @Override\n        public void invalidate() {\n            clearProbes();\n            super.invalidate();\n        }\n\n        @Override\n        public void dispose() {\n            clearProbes();\n            super.dispose();\n        }\n\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/PadDirection.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.NativeEnum;\n\n/**\n * The direction of a {@link Pad}.\n */\npublic enum PadDirection implements NativeEnum<PadDirection> {\n    /** The direction is unknown. */\n    UNKNOWN(0),\n    /** The {@link Pad} is a source pad. */\n    SRC(1),\n    /** The {@link Pad} is a sink pad. */\n    SINK(2);\n\n    private final int value;\n    \n    private PadDirection(int value) {\n        this.value = value;\n    }\n    \n    @Override\n    public int intValue() {\n        return value;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/PadLinkException.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\n/**\n * The exception thrown when a pad link operation returns a non-OK result\n */\npublic class PadLinkException extends GstException {\n\n    private final PadLinkReturn linkResult;\n\n    PadLinkException(PadLinkReturn result) {\n        this(\"failed to link pads (\" + result + \")\", result);\n    }\n\n    PadLinkException(String message, PadLinkReturn result) {\n        super(message);\n        linkResult = result;\n    }\n\n    /**\n     * Get the PadLinkReturn result that caused this exception.\n     * @return PadLinkReturn\n     */\n    public PadLinkReturn getLinkResult() {\n        return linkResult;\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/PadLinkReturn.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n* This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.NativeEnum;\nimport org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue;\n\n/**\n * Result values from {@link Pad#link(Pad)} and friends.\n */\npublic enum PadLinkReturn implements NativeEnum<PadLinkReturn> {\n    /** Link succeeded. */\n    OK(0),\n    /** Pads have no common grandparent. */\n    WRONG_HIERARCHY(-1),\n    /** Pad was already linked. */\n    WAS_LINKED(-2),\n    /** Pads have wrong direction. */\n    WRONG_DIRECTION(-3),\n    /** Pads do not have common format. */\n    NOFORMAT(-4),\n    /** Pads cannot cooperate in scheduling. */\n    NOSCHED(-5),\n    /** Refused for some reason. */\n    @DefaultEnumValue\n    REFUSED(-6);\n    \n    private final int value;\n    \n    PadLinkReturn(int value) {\n        this.value = value;\n    }\n    /**\n     * Gets the integer value of the enum.\n     * @return The integer value for this enum.\n     */\n    @Override\n    public int intValue() {\n        return value;\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/PadMode.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue;\n\n/**\n * The status of a {@link Pad}. After activating a pad, which usually happens when \n * the parent element goes from {@link State#READY} to {@link State#PAUSED}, the \n * PadMode defines if the {@link Pad} operates in push or pull mode.\n */\npublic enum PadMode {\n    /** \n     * Pad will not handle dataflow\n     */\n    @DefaultEnumValue\n    NONE,\n    /**\n     * Pad handles dataflow in downstream push mode\n     */\n    PUSH,\n    /**\n     * Pad handles dataflow in upstream pull mode\n     */\n    PULL;\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/PadPresence.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\n/**\n * Indicates when a {@link Pad} will become available, for use in {@link PadTemplate}\n */\npublic enum PadPresence {\n    /**\n     * The Pad is always available.\n     */\n    ALWAYS,\n    /**\n     * The pad will become available depending on the media stream.\n     */\n    SOMETIMES,\n    /**\n     * The pad is only available on request with {@link Element#getRequestPad(java.lang.String) }\n     */\n    REQUEST;\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/PadProbeInfo.java",
    "content": "/* \n * Copyright (C) 2020 Neil C Smith\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport java.util.Set;\nimport org.freedesktop.gstreamer.event.Event;\nimport org.freedesktop.gstreamer.glib.NativeFlags;\nimport org.freedesktop.gstreamer.lowlevel.GstPadProbeInfo;\nimport org.freedesktop.gstreamer.query.Query;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstPadAPI.GSTPAD_API;\n\n/**\n * Probe info passed in to Pad.PROBE callback.\n */\npublic final class PadProbeInfo {\n    \n    private GstPadProbeInfo info;\n    \n    PadProbeInfo(GstPadProbeInfo info) {\n        this.info = info;\n    }\n    \n    /**\n     * Get the set of flags for the current probe type.\n     * \n     * @return probe type\n     */\n    public Set<PadProbeType> getType() {\n        return NativeFlags.fromInt(PadProbeType.class, info.padProbeType);\n    }\n    \n    /**\n     * Get the Buffer from the probe, or null.\n     * \n     * @return buffer or null\n     */\n    public Buffer getBuffer() {\n        return GSTPAD_API.gst_pad_probe_info_get_buffer(info);\n    }\n\n    /**\n     * Get the Event from the probe, or null.\n     * \n     * @return event or null\n     */\n    public Event getEvent() {\n        return GSTPAD_API.gst_pad_probe_info_get_event(info);\n    }\n\n    /**\n     * Get the query from the probe, or null.\n     * \n     * @return query or null\n     */\n    public Query getQuery() {\n        return GSTPAD_API.gst_pad_probe_info_get_query(info);\n    }\n    \n    void invalidate() {\n        info = null;\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/PadProbeReturn.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\n/**\n * Different return values for Pad probe callbacks\n */\npublic enum PadProbeReturn {\n    /**\n     * Drop data in data probes. For push mode this means that the data item is\n     * not sent downstream. For pull mode, it means that the data item is not\n     * passed upstream. In both cases, no other probes are called for this item\n     * and %GST_FLOW_OK or %TRUE is returned to the caller.\n     */\n    DROP,\n    /**\n     * Normal probe return value. This leaves the probe in place, and defers\n     * decisions about dropping or passing data to other probes, if any. If\n     * there are no other probes, the default behaviour for the probe type\n     * applies ('block' for blocking probes, and 'pass' for non-blocking\n     * probes).\n     */\n    OK,\n    /**\n     * Remove the probe\n     */\n    REMOVE,\n    /**\n     * Pass the data item in the block probe and block on the next item.\n     */\n    PASS,\n    /**\n     * Data has been handled in the probe and will not be forwarded further. For\n     * events and buffers this is the same behaviour as %GST_PAD_PROBE_DROP\n     * (except that in this case you need to unref the buffer or event\n     * yourself). For queries it will also return %TRUE to the caller. The probe\n     * can also modify the #GstFlowReturn value by using the\n     * #GST_PAD_PROBE_INFO_FLOW_RETURN() accessor. Note that the resulting query\n     * must contain valid entries. Since: 1.6\n     */\n    HANDLED;\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/PadProbeType.java",
    "content": "/* \n * Copyright (c) 2020 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport java.util.Collections;\nimport java.util.Set;\nimport org.freedesktop.gstreamer.glib.NativeFlags;\nimport org.freedesktop.gstreamer.lowlevel.GstPadAPI;\n\n/**\n * The different probing types that can occur. When either one of {@link #IDLE}\n * or {@link #BLOCK} is used, the probe will be a blocking probe.\n * <p>\n * For convenience, the various flag combinations are provided as immutable\n * Sets.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/documentation/gstreamer/gstpad.html#GstPadProbeType\"\n * >https://gstreamer.freedesktop.org/documentation/gstreamer/gstpad.html#GstPadProbeType</a>\n */\npublic enum PadProbeType implements NativeFlags<PadProbeType> {\n\n    /* flags to control blocking */\n    /**\n     * Probe idle pads and block while the callback is called.\n     */\n    IDLE(GstPadAPI.GST_PAD_PROBE_TYPE_IDLE),\n    /**\n     * Probe and block pads.\n     */\n    BLOCK(GstPadAPI.GST_PAD_PROBE_TYPE_BLOCK),\n    /* flags to select datatypes */\n    /**\n     * Probe buffers.\n     */\n    BUFFER(GstPadAPI.GST_PAD_PROBE_TYPE_BUFFER),\n    /**\n     * Probe buffer lists.\n     */\n    BUFFER_LIST(GstPadAPI.GST_PAD_PROBE_TYPE_BUFFER_LIST),\n    /**\n     * Probe downstream events.\n     */\n    EVENT_DOWNSTREAM(GstPadAPI.GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM),\n    /**\n     * Probe upstream events.\n     */\n    EVENT_UPSTREAM(GstPadAPI.GST_PAD_PROBE_TYPE_EVENT_UPSTREAM),\n    /**\n     * Probe flush events. This probe has to be explicitly enabled and is not\n     * included in the DOWNSTREAM or UPSTREAM probe types.\n     */\n    EVENT_FLUSH(GstPadAPI.GST_PAD_PROBE_TYPE_EVENT_FLUSH),\n    /**\n     * Probe downstream queries.\n     */\n    QUERY_DOWNSTREAM(GstPadAPI.GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM),\n    /**\n     * Probe upstream queries.\n     */\n    QUERY_UPSTREAM(GstPadAPI.GST_PAD_PROBE_TYPE_QUERY_UPSTREAM),\n    /* flags to select scheduling mode */\n    /**\n     * Probe push.\n     */\n    PUSH(GstPadAPI.GST_PAD_PROBE_TYPE_PUSH),\n    /**\n     * Probe pull.\n     */\n    PULL(GstPadAPI.GST_PAD_PROBE_TYPE_PULL);\n\n    /**\n     * Probe and block at the next opportunity, at data flow or when idle.\n     */\n    public static final Set<PadProbeType> BLOCKING\n            = Collections.unmodifiableSet(NativeFlags.fromInt(PadProbeType.class,\n                    GstPadAPI.GST_PAD_PROBE_TYPE_BLOCKING));\n\n    /**\n     * Probe downstream data (buffers, buffer lists and events).\n     */\n    public static final Set<PadProbeType> DATA_DOWNSTREAM\n            = Collections.unmodifiableSet(NativeFlags.fromInt(PadProbeType.class,\n                    GstPadAPI.GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM));\n\n    /**\n     * Probe upstream data (events).\n     */\n    public static final Set<PadProbeType> DATA_UPSTREAM\n            = Collections.unmodifiableSet(NativeFlags.fromInt(PadProbeType.class,\n                    GstPadAPI.GST_PAD_PROBE_TYPE_DATA_UPSTREAM));\n\n    /**\n     * Probe upstream and downstream data (buffers, buffer lists and events).\n     */\n    public static final Set<PadProbeType> DATA_BOTH\n            = Collections.unmodifiableSet(NativeFlags.fromInt(PadProbeType.class,\n                    GstPadAPI.GST_PAD_PROBE_TYPE_DATA_BOTH));\n\n    /**\n     * Probe and block downstream data (buffers, buffer lists and events).\n     */\n    public static final Set<PadProbeType> BLOCK_DOWNSTREAM\n            = Collections.unmodifiableSet(NativeFlags.fromInt(PadProbeType.class,\n                    GstPadAPI.GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM));\n\n    /**\n     * Probe and block upstream data (events).\n     */\n    public static final Set<PadProbeType> BLOCK_UPSTREAM\n            = Collections.unmodifiableSet(NativeFlags.fromInt(PadProbeType.class,\n                    GstPadAPI.GST_PAD_PROBE_TYPE_BLOCK_UPSTREAM));\n\n    /**\n     * Probe upstream and downstream events.\n     */\n    public static final Set<PadProbeType> EVENT_BOTH\n            = Collections.unmodifiableSet(NativeFlags.fromInt(PadProbeType.class,\n                    GstPadAPI.GST_PAD_PROBE_TYPE_EVENT_BOTH));\n\n    /**\n     * Probe upstream and downstream queries.\n     */\n    public static final Set<PadProbeType> QUERY_BOTH\n            = Collections.unmodifiableSet(NativeFlags.fromInt(PadProbeType.class,\n                    GstPadAPI.GST_PAD_PROBE_TYPE_QUERY_BOTH));\n\n    /**\n     * Probe upstream events and queries and downstream buffers, buffer lists,\n     * events and queries.\n     */\n    public static final Set<PadProbeType> ALL_BOTH\n            = Collections.unmodifiableSet(NativeFlags.fromInt(PadProbeType.class,\n                    GstPadAPI.GST_PAD_PROBE_TYPE_ALL_BOTH));\n\n    /**\n     * Probe push and pull.\n     */\n    public static final Set<PadProbeType> SCHEDULING\n            = Collections.unmodifiableSet(NativeFlags.fromInt(PadProbeType.class,\n                    GstPadAPI.GST_PAD_PROBE_TYPE_SCHEDULING));\n\n    private final int value;\n\n    private PadProbeType(int value) {\n        this.value = value;\n    }\n\n    @Override\n    public int intValue() {\n        return value;\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/PadTemplate.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (C) 2007, 2008 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wtay@chello.be>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.Natives;\nimport static org.freedesktop.gstreamer.lowlevel.GstPadTemplateAPI.GSTPADTEMPLATE_API;\n\n/**\n * Padtemplates describe the possible media types a {@link Pad} or an\n * {@link ElementFactory} can handle. This allows for both inspection of handled\n * types before loading the element plugin as well as identifying pads on\n * elements that are not yet created (request or sometimes pads).\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPadTemplate.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPadTemplate.html</a>\n * <p>\n * Pad and PadTemplates have {@code Caps} attached to it to describe the media\n * type they are capable of dealing with. {@link #getCaps} is used to get the\n * caps of a PadTemplate. It is not possible to modify the caps of a PadTemplate\n * after creation.\n */\npublic class PadTemplate extends GstObject {\n\n    public static final String GTYPE_NAME = \"GstPadTemplate\";\n\n    /**\n     * Creates a new proxy for PadTemplate.\n     * <p>\n     * This is only for internal use.\n     *\n     * @param init internal initialization data.\n     */\n    PadTemplate(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Creates a new pad template with a name according to the given template,\n     * with the given arguments and {@link PadPresence#ALWAYS }\n     *\n     * @param nameTemplate the name template.\n     * @param direction the direction of the template.\n     * @param caps a {@code Caps} set for the template.\n     */\n    public PadTemplate(String nameTemplate, PadDirection direction, Caps caps) {\n        this(Natives.initializer(GSTPADTEMPLATE_API.ptr_gst_pad_template_new(nameTemplate, direction, PadPresence.ALWAYS, caps)));\n    }\n\n    /**\n     * Creates a new pad template with a name according to the given template\n     * and with the given arguments.\n     *\n     * @param nameTemplate the name template.\n     * @param direction the direction of the template.\n     * @param presence the presence of the pad, which controls the lifetime.\n     * @param caps a {@code Caps} set for the template.\n     */\n    public PadTemplate(String nameTemplate, PadDirection direction, PadPresence presence, Caps caps) {\n        this(Natives.initializer(GSTPADTEMPLATE_API.ptr_gst_pad_template_new(nameTemplate, direction, presence, caps)));\n    }\n\n    /**\n     * Gets the {@link Caps} set on this {@code PadTemplate}\n     *\n     * @return the media type on this template.\n     */\n    public Caps getCaps() {\n        return GSTPADTEMPLATE_API.gst_pad_template_get_caps(this);\n    }\n\n    /**\n     * Gets the name of this template\n     *\n     * @return the name of this template\n     */\n    public String getTemplateName() {\n        return get(\"name-template\").toString();\n    }\n\n    /**\n     * Gets the direction of this template\n     *\n     * @return {@link PadDirection}\n     */\n    public PadDirection getDirection() {\n        Object d = get(\"direction\");\n        if (d instanceof Number) {\n            return PadDirection.values()[((Number) d).intValue()];\n        }\n        return null;\n    }\n\n    /**\n     * Gets presence of this template\n     *\n     * @return {@link PadPresence}\n     */\n    public PadPresence getPresence() {\n        Object p = get(\"presence\");\n        if (p instanceof Number) {\n            return PadPresence.values()[((Number) p).intValue()];\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/Pipeline.java",
    "content": "/* \n * Copyright (c) 2021 Neil C Smith\n * Copyright (c) 2008 Wayne Meissner\n * Copyright (C) 2000 Erik Walthinsen <omega@cse.ogi.edu>\n *               2005 Wim Taymans <wim@fluendo.com>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport com.sun.jna.Pointer;\nimport java.util.EnumSet;\nimport java.util.Set;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicReference;\nimport java.util.logging.Logger;\nimport org.freedesktop.gstreamer.event.SeekFlags;\nimport org.freedesktop.gstreamer.event.SeekType;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GstObjectPtr;\nimport org.freedesktop.gstreamer.query.Query;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstElementAPI.GSTELEMENT_API;\nimport static org.freedesktop.gstreamer.lowlevel.GstPipelineAPI.GSTPIPELINE_API;\nimport static org.freedesktop.gstreamer.lowlevel.GstQueryAPI.GSTQUERY_API;\n\n/**\n * A {@code Pipeline} is a special {@link Bin} used as the top level container\n * for the filter graph. The Pipeline will manage the selection and distribution\n * of a global {@link Clock} as well as provide a {@link Bus} to the\n * application. It will also implement a default behaviour for managing seek\n * events (see {@link #seek seek}).\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPipeline.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPipeline.html</a>\n * <p>\n * Elements are added and removed from the pipeline using the {@code Bin}\n * methods like {@link Bin#add add} and {@link Bin#remove remove}.\n * <p>\n * Before changing the state of the Pipeline (see {@link Element}) a {@link Bus}\n * can be retrieved with {@link #getBus getBus}. This bus can then be used to\n * receive {@link Message}s from the elements in the pipeline.\n * <p>\n * By default, a Pipeline will automatically flush the pending Bus messages when\n * going to the NULL state to ensure that no circular references exist when no\n * messages are read from the Bus. This behaviour can be changed with\n * {@link #setAutoFlushBus setAutoFlushBus}\n * <p>\n * When the Pipeline performs the PAUSED to PLAYING state change it will select\n * a clock for the elements. The clock selection algorithm will by default\n * select a clock provided by an element that is most upstream (closest to the\n * source). For live pipelines (ones that return\n * {@link StateChangeReturn#NO_PREROLL} from the\n * {@link Element#setState setState} call) this will select the clock provided\n * by the live source. For normal pipelines this will select a clock provided by\n * the sinks (most likely the audio sink). If no element provides a clock, a\n * default SystemClock is used.\n *\n * <p>\n * The clock selection can be controlled with the gst_pipeline_use_clock()\n * method, which will enforce a given clock on the pipeline. With\n * gst_pipeline_auto_clock() the default clock selection algorithm can be\n * restored.\n *\n * <p>\n * A Pipeline maintains a stream time for the elements. The stream time is\n * defined as the difference between the current clock time and the base time.\n * When the pipeline goes to READY or a flushing seek is performed on it, the\n * stream time is reset to 0. When the pipeline is set from PLAYING to PAUSED,\n * the current clock time is sampled and used to configure the base time for the\n * elements when the pipeline is set to PLAYING again. This default behaviour\n * can be changed with the gst_pipeline_set_new_stream_time() method.\n *\n * When sending a flushing seek event to a GstPipeline (see {@link #seek seek}),\n * it will make sure that the pipeline is properly PAUSED and resumed as well as\n * set the new stream time to 0 when the seek succeeded.\n */\npublic class Pipeline extends Bin {\n\n    public static final String GST_NAME = \"pipeline\";\n    public static final String GTYPE_NAME = \"GstPipeline\";\n\n    private static Logger LOG = Logger.getLogger(Pipeline.class.getName());\n    \n    private final Handle handle;\n\n    protected Pipeline(Initializer init) {\n        this(new Handle(init.ptr.as(GstObjectPtr.class, GstObjectPtr::new), init.ownsHandle), init.needRef);\n    }\n    \n    Pipeline(Handle handle, boolean needRef) {\n        super(handle, needRef);\n        this.handle = handle;\n        handle.busRef.set(GSTPIPELINE_API.gst_pipeline_get_bus(this));\n    }\n\n    /**\n     * Creates a new instance of Pipeline with a unique name.\n     */\n    public Pipeline() {\n        this(Natives.initializer(GSTPIPELINE_API.ptr_gst_pipeline_new(null), false));\n    }\n\n    /**\n     * Creates a new instance of Pipeline with the given name.\n     *\n     * @param name The name used to identify this pipeline.\n     */\n    public Pipeline(String name) {\n        this(initializer(name));\n    }\n\n    private static Initializer initializer(String name) {\n        Pointer new_pipeline = GSTPIPELINE_API.ptr_gst_pipeline_new(name);\n        return Natives.initializer(new_pipeline, false);\n    }\n\n    /**\n     * Usually, when a pipeline goes from READY to NULL state, it automatically\n     * flushes all pending messages on the bus, which is done for refcounting\n     * purposes, to break circular references.\n     * <p>\n     * This means that applications that update state using (async) bus messages\n     * (e.g. do certain things when a pipeline goes from PAUSED to READY) might\n     * not get to see messages when the pipeline is shut down, because they\n     * might be flushed before they can be dispatched in the main thread. This\n     * behaviour can be disabled using this function.\n     * <p>\n     * It is important that all messages on the bus are handled when the\n     * automatic flushing is disabled else memory leaks will be introduced.\n     * <p>\n     * MT safe.\n     *\n     * @param flush whether or not to automatically flush the bus when the\n     * pipeline goes from READY to NULL state\n     */\n    public void setAutoFlushBus(boolean flush) {\n        GSTPIPELINE_API.gst_pipeline_set_auto_flush_bus(this, flush);\n    }\n\n    /**\n     * Checks if the pipeline will automatically flush messages when going to\n     * the NULL state.\n     * <p>\n     * MT safe.\n     *\n     * @return true if the pipeline automatically flushes messages.\n     */\n    public boolean getAutoFlushBus() {\n        return GSTPIPELINE_API.gst_pipeline_get_auto_flush_bus(this);\n    }\n\n    /**\n     * Set the clock for pipeline. The clock will be distributed to all the\n     * elements managed by the pipeline.\n     * <p>\n     * MT safe\n     *\n     * @param clock The {@link Clock} to use\n     * @return true if the clock could be set on the pipeline, false if some\n     * element did not accept the clock.\n     *\n     */\n    public boolean setClock(Clock clock) {\n        return GSTPIPELINE_API.gst_pipeline_set_clock(this, clock);\n    }\n\n    /**\n     * Return the current {@link Clock} used by the pipeline.\n     *\n     * @return The {@link Clock} currently in use.\n     */\n    @Override\n    public Clock getClock() {\n        return GSTPIPELINE_API.gst_pipeline_get_clock(this);\n    }\n\n    /**\n     * Force the Pipeline to use the a specific clock. The pipeline will always\n     * use the given clock even if new clock providers are added to this\n     * pipeline.\n     * <p>\n     * MT safe\n     *\n     * @param clock The {@link Clock} to use. If clock is null, all clocking is\n     * disabled, and the pipeline will run as fast as possible.\n     *\n     */\n    public void useClock(Clock clock) {\n        GSTPIPELINE_API.gst_pipeline_use_clock(this, clock);\n    }\n\n    /**\n     * Gets the {@link Bus} this pipeline uses for messages.\n     *\n     * @return The {@link Bus} that this pipeline uses.\n     */\n    @Override\n    public Bus getBus() {\n        return handle.busRef.get();\n    }\n\n    /**\n     * Sets the position in the media stream to time in nanoseconds.\n     * <p>\n     * Prefer use of\n     * {@link Element#seekSimple(org.freedesktop.gstreamer.Format, java.util.Set, long)}.\n     *\n     * @param time The time to change the position to.\n     * @return true if seek is successful\n     */\n    // @TODO move seek and query methods on to element?\n    public boolean seek(long time) {\n        return seek(time, TimeUnit.NANOSECONDS);\n    }\n\n    /**\n     * Sets the current position in the media stream.\n     * <p>\n     * Prefer use of\n     * {@link Element#seekSimple(org.freedesktop.gstreamer.Format, java.util.Set, long)}.\n     *\n     * @param time the time to change the position to.\n     * @param unit the {@code TimeUnit} the time is expressed in.\n     * @return true if seek is successful\n     */\n    public boolean seek(long time, TimeUnit unit) {\n        return seek(1.0, Format.TIME, EnumSet.of(SeekFlags.FLUSH, SeekFlags.KEY_UNIT),\n                SeekType.SET, TimeUnit.NANOSECONDS.convert(time, unit),\n                SeekType.NONE, -1);\n    }\n\n    /**\n     * Seeks to a new position in the media stream.\n     *\n     * <p>\n     * The start and stop values are expressed in format.\n     * <p>\n     * A rate of 1.0 means normal playback rate, 2.0 means double speed.\n     * Negative values means backwards playback. A value of 0.0 for the rate is\n     * not allowed and should be accomplished instead by PAUSING the pipeline.\n     * <p>\n     * A pipeline has a default playback segment configured with a start\n     * position of 0, a stop position of -1 and a rate of 1.0. The currently\n     * configured playback segment can be queried with #GST_QUERY_SEGMENT.\n     * <p>\n     * startType and stopType specify how to adjust the currently configured\n     * start and stop fields in segment. Adjustments can be made relative or\n     * absolute to the last configured values. A type of {@link SeekType#NONE}\n     * means that the position should not be updated.\n     * <p>\n     * When the rate is positive and start has been updated, playback will start\n     * from the newly configured start position.\n     * <p>\n     * For negative rates, playback will start from the newly configured stop\n     * position (if any). If the stop position if updated, it must be different\n     * from -1 for negative rates.\n     * <p>\n     * It is not possible to seek relative to the current playback position, to\n     * do this, PAUSE the pipeline, query the current playback position with\n     * {@link org.gstreamer.Pipeline#queryPosition queryPosition} and update the\n     * playback segment current position with a {@link SeekType#SET} to the\n     * desired position.\n     *\n     * @param rate the new playback rate\n     * @param format the format of the seek values\n     * @param seekFlags the seek flags\n     * @param startType the type and flags for the new start position\n     * @param start the value of the new start position\n     * @param stopType the type and flags for the new stop position\n     * @param stop the value of the new stop position\n     * @return true if seek is successful\n     */\n    // for compatibility\n    public boolean seek(double rate, Format format, EnumSet<SeekFlags> seekFlags,\n            SeekType startType, long start, SeekType stopType, long stop) {\n        return super.seek(rate, format, seekFlags, startType, start, stopType, stop);\n    }\n    \n    @Override\n    public boolean seek(double rate, Format format, Set<SeekFlags> seekFlags,\n            SeekType startType, long start, SeekType stopType, long stop) {\n        return super.seek(rate, format, seekFlags, startType, start, stopType, stop);\n    }\n    \n    /**\n     * Gets the current position in the media stream.\n     *\n     * @param unit the {@code TimeUnit} to return the position in terms of.\n     * @return a time value representing the current position in units of unit.\n     */\n    public long queryPosition(TimeUnit unit) {\n        return unit.convert(queryPosition(Format.TIME), TimeUnit.NANOSECONDS);\n    }\n\n    @Override\n    public long queryPosition(Format format) {\n        return super.queryPosition(format);\n    }\n\n    /**\n     * Gets the time duration of the current media stream.\n     *\n     * @param unit the {@code TimeUnit} to return the position in.\n     * @return The total duration of the current media stream.\n     */\n    public long queryDuration(TimeUnit unit) {\n        return unit.convert(queryDuration(Format.TIME), TimeUnit.NANOSECONDS);\n    }\n\n    @Override\n    public long queryDuration(Format format) {\n        return super.queryDuration(format);\n    }\n\n    /**\n     * Gets the {@link Segment} for the current media stream in terms of time.\n     *\n     * @return The information regarding the current {@code Segment}.\n     */\n    public Segment querySegment() {\n        return querySegment(Format.TIME);\n    }\n\n    /**\n     * Gets the {@link Segment} for the current media stream in terms of the\n     * specified {@link Format}.\n     *\n     * @param format the {@code Format} to return the segment in.\n     * @return The information regarding the current {@code Segment}.\n     */\n    public Segment querySegment(Format format) {\n        Query qry = GSTQUERY_API.gst_query_new_segment(format);\n        GSTELEMENT_API.gst_element_query(this, qry);\n        double[] rate = {0.0D};\n        Format[] fmt = {Format.UNDEFINED};\n        long[] start_value = {0};\n        long[] stop_value = {0};\n        GSTQUERY_API.gst_query_parse_segment(qry, rate, fmt, start_value, stop_value);\n        return new Segment(rate[0], fmt[0], start_value[0], stop_value[0]);\n    }\n    \n    static class Handle extends Bin.Handle {\n        \n        private final AtomicReference<Bus> busRef;\n        \n        public Handle(GstObjectPtr ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n            this.busRef = new AtomicReference<>();\n        }\n\n        @Override\n        public void invalidate() {\n            disposeBus();\n            super.invalidate();\n        }\n\n        @Override\n        public void dispose() {\n            disposeBus();\n            super.dispose();\n        }\n\n        private void disposeBus() {\n            Bus bus = busRef.getAndSet(null);\n            if (bus != null) {\n                bus.dispose();\n            }\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/Plugin.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (C) 2007 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wtay@chello.be>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstPluginAPI.GSTPLUGIN_API;\n\n/**\n * Container for features loaded from a shared object module\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPlugin.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPlugin.html</a>\n * <p>\n * GStreamer is extensible, so {@link Element} instances can be loaded at\n * runtime. A plugin system can provide one or more of the basic GStreamer\n * {@link PluginFeature} subclasses.\n * <p>\n * A plugin should export a symbol <code>gst_plugin_desc</code> that is a struct\n * of type GstPluginDesc. the plugin loader will check the version of the core\n * library the plugin was linked against and will create a new Plugin. It will\n * then call the #GstPluginInitFunc function that was provided in the\n * <symbol>gst_plugin_desc</symbol>.\n * <p>\n * Once you have a handle to a #GstPlugin (e.g. from the #GstRegistryPool), you\n * can add any object that subclasses #GstPluginFeature.\n * <p>\n * Use gst_plugin_find_feature() and gst_plugin_get_feature_list() to find\n * features in a plugin.\n * <p>\n * Usually plugins are always automatically loaded so you don't need to call\n * {@link #loadByName} explicitly to bring it into memory. There are options to\n * statically link plugins to an app or even use GStreamer without a plugin\n * repository in which case {@link #loadByName} can be needed to bring the\n * plugin into memory.\n * <p>\n * @see PluginFeature\n * @see ElementFactory\n */\npublic class Plugin extends GstObject {\n\n    public static final String GTYPE_NAME = \"GstPlugin\";\n\n    /**\n     * Creates a new instance of GstElement\n     *\n     * @param init internal initialization data.\n     */\n    Plugin(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Load the named plugin.\n     *\n     * @param pluginName\n     * @return A new Plugin reference if the plugin was loaded, else null.\n     */\n    public static Plugin loadByName(String pluginName) {\n        return GSTPLUGIN_API.gst_plugin_load_by_name(pluginName);\n    }\n\n    /**\n     * Get the short name of the plugin.\n     *\n     * @return the name of the plugin.\n     */\n    @Override\n    public String getName() {\n        return GSTPLUGIN_API.gst_plugin_get_name(this);\n    }\n\n    /**\n     * Get the long descriptive name of the plugin.\n     *\n     * @return The long name of the plugin.\n     */\n    public String getDescription() {\n        return GSTPLUGIN_API.gst_plugin_get_description(this);\n    }\n\n    /**\n     * Get the filename of the plugin.\n     *\n     * @return The filename of the plugin.\n     */\n    public String getFilename() {\n        return GSTPLUGIN_API.gst_plugin_get_filename(this);\n    }\n\n    /**\n     * Get the version of the plugin.\n     *\n     * @return The version of the plugin.\n     */\n    public String getVersion() {\n        return GSTPLUGIN_API.gst_plugin_get_version(this);\n    }\n\n    /**\n     * Get the license of the plugin.\n     *\n     * @return The license of the plugin.\n     */\n    public String getLicense() {\n        return GSTPLUGIN_API.gst_plugin_get_license(this);\n    }\n\n    /**\n     * Get the source module the plugin belongs to.\n     *\n     * @return The source of the plugin.\n     */\n    public String getSource() {\n        return GSTPLUGIN_API.gst_plugin_get_source(this);\n    }\n\n    /**\n     * Get the package the plugin belongs to.\n     *\n     * @return The package of the plugin.\n     */\n    public String getPackage() {\n        return GSTPLUGIN_API.gst_plugin_get_package(this);\n    }\n\n    /**\n     * Get the URL where the plugin comes from.\n     *\n     * @return The origin of the plugin.\n     */\n    public String getOrigin() {\n        return GSTPLUGIN_API.gst_plugin_get_origin(this);\n    }\n\n    /**\n     * Get the release date (and possibly time) in form of a string, if\n     * available.\n     *\n     * For normal GStreamer plugin releases this will usually just be a date in\n     * the form of \"YYYY-MM-DD\", while pre-releases and builds from git may\n     * contain a time component after the date as well, in which case the string\n     * will be formatted like \"YYYY-MM-DDTHH:MMZ\" (e.g.\n     * \"2012-04-30T09:30Z\").Test\n     */\n    public String getReleaseDateString() {\n        return GSTPLUGIN_API.gst_plugin_get_release_date_string(this);\n    }\n\n    /**\n     * Queries if the plugin is loaded into memory.\n     *\n     * @return true if it is loaded, false otherwise.\n     */\n    public boolean isLoaded() {\n        return GSTPLUGIN_API.gst_plugin_is_loaded(this);\n    }\n\n//    /**\n//     * Ensures this plugin is loaded.\n//     *\n//     * @return a potentially new <tt>Plugin</tt> reference.\n//     */\n//    public Plugin load() {\n//        return GSTPLUGIN_API.gst_plugin_load(this);\n//    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/PluginFeature.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2007 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wtay@chello.be>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.NativeEnum;\nimport static org.freedesktop.gstreamer.lowlevel.GstObjectAPI.GSTOBJECT_API;\nimport static org.freedesktop.gstreamer.lowlevel.GstPluginFeatureAPI.GSTPLUGINFEATURE_API;\n\n/**\n * Base class for contents of a {@link Plugin}\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPluginFeature.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPluginFeature.html</a>\n * <p>\n * This is a base class for anything that can be added to a Plugin.\n *\n * @see Plugin\n */\npublic class PluginFeature extends GstObject {\n\n    public static final String GTYPE_NAME = \"GstPluginFeature\";\n\n    /**\n     * Element priority ranks. Defines the order in which the autoplugger (or\n     * similar rank-picking mechanisms, such as e.g.\n     * gst_element_make_from_uri()) will choose this element over an alternative\n     * one with the same function.\n     *\n     * These constants serve as a rough guidance for defining the rank of a\n     * GstPluginFeature. Any value is valid, including values bigger than\n     * GST_RANK_PRIMARY .\n     */\n    public enum Rank implements NativeEnum<Rank> {\n\n        /**\n         * Will be chosen last or not at all.\n         */\n        NONE(0),\n\n        /**\n         * Unlikely to be chosen.\n         */\n        MARGINAL(64),\n        \n        /**\n         * Likely to be chosen.\n         */\n        SECONDARY(128),\n        \n        /**\n         * Will be chosen first.\n         */\n        PRIMARY(256);\n\n        private final int value;\n\n        private Rank(int value) {\n            this.value = value;\n        }\n\n        @Override\n        public int intValue() {\n            return value;\n        }\n    }\n\n    /**\n     * Creates a new instance of PluginFeature\n     */\n    PluginFeature(Initializer init) {\n        super(init);\n    }\n\n    @Override\n    public String toString() {\n        return getName();\n    }\n\n    /**\n     * Gets the name of a plugin feature.\n     *\n     * @return The name.\n     */\n    @Override\n    public String getName() {\n        return GSTOBJECT_API.gst_object_get_name(this);\n    }\n\n    /**\n     * Sets the name of the plugin feature, getting rid of the old name if there\n     * was one.\n     *\n     * @param name The name to set.\n     */\n    @Override\n    public boolean setName(String name) {\n        GSTOBJECT_API.gst_object_set_name(this, name);\n        return true;\n    }\n\n    /**\n     * Set the rank for the plugin feature. Specifies a rank for a plugin\n     * feature, so that autoplugging uses the most appropriate feature.\n     *\n     * @param rank The rank value - higher number means more priority rank\n     */\n    public void setRank(int rank) {\n        GSTPLUGINFEATURE_API.gst_plugin_feature_set_rank(this, rank);\n    }\n\n    /**\n     * Set the rank for the plugin feature. Specifies a rank for a plugin\n     * feature, so that autoplugging uses the most appropriate feature.\n     *\n     * @param rank The rank value\n     */\n    public void setRank(Rank rank) {\n        setRank(rank.intValue());\n    }\n\n    /**\n     * Gets the rank of a plugin feature.\n     *\n     * @return The rank of the feature.\n     */\n    public int getRank() {\n        return GSTPLUGINFEATURE_API.gst_plugin_feature_get_rank(this);\n    }\n\n    /**\n     * Checks whether the given plugin feature is at least the required version.\n     *\n     * @param major Minimum required major version\n     * @param minor Minimum required minor version\n     * @param micro Minimum required micro version\n     * @return true if the plugin feature has at least the required version,\n     * otherwise false.\n     */\n    public boolean checkVersion(int major, int minor, int micro) {\n        return GSTPLUGINFEATURE_API.gst_plugin_feature_check_version(this, minor, minor, micro);\n    }\n\n    /**\n     * Get the name of the plugin that provides this feature.\n     *\n     * @return the name of the plugin that provides this feature, or NULL if the\n     * feature is not associated with a plugin.\n     */\n    public String getPluginName() {\n        return GSTPLUGINFEATURE_API.gst_plugin_feature_get_plugin_name(this);\n    }\n\n    /**\n     * Get the plugin that provides this feature.\n     *\n     * @return the plugin that provides this feature, or NULL.\n     */\n    public Plugin getPlugin() {\n        return GSTPLUGINFEATURE_API.gst_plugin_feature_get_plugin(this);\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/Promise.java",
    "content": "/*\n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2018 Vinicius Tona\n * Copyright (c) 2018 Antonio Morales\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstPromiseAPI.GSTPROMISE_API;\n\nimport org.freedesktop.gstreamer.glib.NativeObject;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback;\n\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.glib.Natives;\n\n/**\n * A miniobject for future/promise-like functionality\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPromise.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPromise.html</a>\n * <p>\n */\n@Gst.Since(minor = 14)\npublic class Promise extends MiniObject {\n\n    public static final String GTYPE_NAME = \"GstPromise\";\n\n    private GstCallback changeFunction;\n    \n    /**\n     * Creates a new instance of Promise. This constructor is used internally.\n     *\n     * @param init internal initialization data.\n     */\n    Promise(final Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Creates a new instance of promise\n     */\n    public Promise() {\n        this(Natives.initializer(GSTPROMISE_API.ptr_gst_promise_new()));\n        Gst.checkVersion(1, 14); // @TODO ideally this check would be before native call!\n    }\n\n    /**\n     * Creates a new instance of promise with a callback attached.\n     *\n     * @param listener Listener to be called whenever the state of a\n     * {@link Promise} is changed\n     */\n    public Promise(final PROMISE_CHANGE listener) {\n        this(new GstCallback() {\n            public void callback(Promise promise, Pointer userData) {\n                listener.onChange(promise);\n            }\n        });\n    }\n    \n    private Promise(GstCallback callback) {\n        this(Natives.initializer(GSTPROMISE_API\n                .ptr_gst_promise_new_with_change_func(callback, null, null)));\n        this.changeFunction = callback;\n    }\n\n    /**\n     * Wait for the promise to move out of the PENDING {@link PromiseResult}\n     * state. If the promise is not in PENDING then it will immediately return.\n     *\n     * @return the {@link PromiseResult} of the promise.\n     */\n    public PromiseResult waitResult() {\n        return GSTPROMISE_API.gst_promise_wait(this);\n    }\n\n    /**\n     * Set a reply on the promise.\n     *\n     * Will wake up any waiters on the promise with the REPLIED\n     * {@link PromiseResult} state. If the promise has already been interrupted\n     * than the replied will not be visible to any waiters\n     *\n     * @param structure the {@link Structure} to reply the promise with, caller\n     * should not use this structure afterward as it is invalidated through\n     * {@link NativeObject#invalidate()}\n     */\n    public void reply(final Structure structure) {\n        GSTPROMISE_API.gst_promise_reply(this, structure);\n    }\n\n    /**\n     * Interrupt waiting for the result of the promise.\n     *\n     * Any waiters on the promise will receive the INTERRUPTED\n     * {@link PromiseResult} state.\n     */\n    public void interrupt() {\n        GSTPROMISE_API.gst_promise_interrupt(this);\n    }\n\n    /**\n     * Expire a promise.\n     *\n     * Any waiters on the promise will received the EXPIRED\n     * {@link PromiseResult} state.\n     */\n    public void expire() {\n        GSTPROMISE_API.gst_promise_expire(this);\n    }\n\n    /**\n     * Retrieve the reply set on the promise.\n     *\n     * The state of the promise must be in the REPLIED {@link PromiseResult}\n     * state. The return structure is owned by the promise and thus cannot be\n     * modified.\n     *\n     * @return the {@link Structure} set on the promise reply.\n     */\n    public Structure getReply() {\n        return Structure.objectFor(GSTPROMISE_API.ptr_gst_promise_get_reply(this), false, false);\n    }\n\n    /**\n     * Called whenever the state of the promise is changed from PENDING to any\n     * other {@link PromiseResult}\n     */\n    public static interface PROMISE_CHANGE {\n\n        /**\n         * Called whenever the state of the promise is changed from PENDING to\n         * any other {@link PromiseResult}\n         *\n         * @param promise the original promise that had the callback attached to\n         */\n        public void onChange(Promise promise);\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/PromiseResult.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2018 Antonio Morales\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue;\n\n/**\n * The result of a {@link Promise}\n * Available since GStreamer 1.14\n */\n@Gst.Since(minor = 14)\npublic enum PromiseResult {\n    /** Initial state. Waiting for transition to any other state. */\n    @DefaultEnumValue\n    PENDING,\n    /** Interrupted by the consumer as it doesn't want the value anymore. */\n    INTERRUPTED,\n    /** A producer marked a reply. */\n    REPLIED,\n    /** The promise expired (the carrying object lost all refs) and the promise\n     * will never be fulfilled. */\n    EXPIRED\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/Range.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * Copyright (C) 2009 Tamas Korodi <kotyo@zamba.fm>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.lowlevel.GValueAPI;\nimport static org.freedesktop.gstreamer.lowlevel.GstValueAPI.GSTVALUE_API;\n\n/**\n * Represents a range of float, double, int, fraction types stored in a GValue \n * @author kotyo\n *\n */\npublic class Range {\n\t// there are multiple native types\n\t//public static final String GTYPE_NAME = \"GstDoubleRange\";\n\n\tprivate GValueAPI.GValue value; \n\t\n\tRange(GValueAPI.GValue value) {\n\t\tthis.value = value;\n\t}\n\t\n\t/**\n\t * Gets the minimum fraction of the range\n\t * @return minimum fraction of the range\n\t */\n\tpublic Fraction getMinFraction() {\n\t\tGValueAPI.GValue frMin = GSTVALUE_API.gst_value_get_fraction_range_min(value); \n\t\tint num = GSTVALUE_API.gst_value_get_fraction_numerator(frMin);\n\t\tint denom = GSTVALUE_API.gst_value_get_fraction_denominator(frMin);\n\t\treturn new Fraction(num, denom);\n\t}\n\n\t/**\n\t * Gets the maximum fraction of the range\n\t * @return maximum fraction of the range\n\t */\n\tpublic Fraction getMaxFraction() {\n\t\tGValueAPI.GValue frMax = GSTVALUE_API.gst_value_get_fraction_range_max(value); \n\t\tint num = GSTVALUE_API.gst_value_get_fraction_numerator(frMax);\n\t\tint denom = GSTVALUE_API.gst_value_get_fraction_denominator(frMax);\n\t\treturn new Fraction(num, denom);\t\t\n\t}\n\n\t/**\n\t * Gets the minimum double of the range\n\t * @return minimum double of the range\n\t */\n\tpublic double getMinDouble() {\n\t\treturn GSTVALUE_API.gst_value_get_double_range_min(value);\n\t}\n\t\n\t/**\n\t * Gets the maximum double of the range\n\t * @return maximum double of the range\n\t */\n\tpublic double getMaxDouble() {\n\t\treturn GSTVALUE_API.gst_value_get_double_range_max(value);\n\t}\n\t\n\t/**\n\t * Gets the minimum integer of the range\n\t * @return minimum integer of the range\n\t */\n\tpublic int getMinInt() {\n\t\treturn GSTVALUE_API.gst_value_get_int_range_min(value);\n\t}\n\t\n\t/**\n\t * Gets the maximum integer of the range\n\t * @return maximum integer of the range\n\t */\n\tpublic int getMaxInt() {\n\t\treturn GSTVALUE_API.gst_value_get_int_range_max(value);\n\t}\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/Registry.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wtay@chello.be>\n *                    2005 David A. Schleef <ds@schleef.org>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.stream.Collectors;\nimport org.freedesktop.gstreamer.glib.Natives;\n\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI.GList;\nimport static org.freedesktop.gstreamer.lowlevel.GstPluginAPI.GSTPLUGIN_API;\nimport static org.freedesktop.gstreamer.lowlevel.GstRegistryAPI.GSTREGISTRY_API;\nimport static org.freedesktop.gstreamer.lowlevel.GstPluginFeatureAPI.GSTPLUGINFEATURE_API;\n\n/**\n * Abstract base class for management of {@link Plugin} objects.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstRegistry.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstRegistry.html</a>\n * <p>\n * One registry holds the metadata of a set of plugins.\n * All registries build the RegistryPool.\n * <p>\n * <b>Design</b>:\n * <p>\n * The Registry object is a list of plugins and some methods for dealing\n * with them. Plugins are matched 1-1 with a file on disk, and may or may\n * not be loaded at a given time. There may be multiple Registry objects,\n * but the \"default registry\" is the only object that has any meaning to the\n * core.\n * <p>\n * The registry.xml file is actually a cache of plugin information. This is\n * unlike versions prior to 0.10, where the registry file was the primary source\n * of plugin information, and was created by the gst-register command.\n * <p>\n * The primary source, at all times, of plugin information is each plugin file\n * itself. Thus, if an application wants information about a particular plugin,\n * or wants to search for a feature that satisfies given criteria, the primary\n * means of doing so is to load every plugin and look at the resulting\n * information that is gathered in the default registry. Clearly, this is a time\n * consuming process, so we cache information in the registry.xml file.\n * <p>\n * On startup, plugins are searched for in the plugin search path. This path can\n * be set directly using the GST_PLUGIN_PATH environment variable. The registry\n * file is loaded from ~/.gstreamer-$GST_MAJORMINOR/registry-$ARCH.xml or the\n * file listed in the GST_REGISTRY environment variable. The only reason to change the\n * registry location is for testing.\n * <p>\n * For each plugin that is found in the plugin search path, there could be 3\n * possibilities for cached information:\n * <ol>\n *   <li>\n *     <para>the cache may not contain information about a given file.</para>\n *   </li>\n *   <li>\n *     <para>the cache may have stale information.</para>\n *   </li>\n *   <li>\n *     <para>the cache may have current information.</para>\n *   </li>\n * </ol>\n * <p>\n * In the first two cases, the plugin is loaded and the cache updated. In\n * addition to these cases, the cache may have entries for plugins that are not\n * relevant to the current process. These are marked as not available to the\n * current process. If the cache is updated for whatever reason, it is marked\n * dirty.\n * <p>\n * A dirty cache is written out at the end of initialization. Each entry is\n * checked to make sure the information is minimally valid. If not, the entry is\n * simply dropped.\n * <p>\n * <bold>Implementation notes:</bold>\n * <p>\n * The \"cache\" and \"default registry\" are different concepts and can represent\n * different sets of plugins. For various reasons, at init time, the cache is\n * stored in the default registry, and plugins not relevant to the current\n * process are marked with the %GST_PLUGIN_FLAG_CACHED bit. These plugins are\n * removed at the end of intitialization.\n */\npublic class Registry extends GstObject {\n    public static final String GTYPE_NAME = \"GstRegistry\";\n\n    /** Creates a new instance of Registry */\n    Registry(Initializer init) {\n        super(init);\n    }\n    \n    /**\n     * Find a plugin in the registry.\n     * \n     * @param name The plugin name to find.\n     * @return The plugin with the given name or null if the plugin was not found.\n     */\n    public Plugin findPlugin(String name) {\n        return GSTREGISTRY_API.gst_registry_find_plugin(this, name);\n    }\n    /**\n     * Add the plugin to the registry. The plugin-added signal will be emitted.\n     *\n     * @param plugin the {@link Plugin} to add\n     * @return true on success.\n     */\n    public boolean addPlugin(Plugin plugin) {\n        return GSTREGISTRY_API.gst_registry_add_plugin(this, plugin);\n    }\n    \n    /**\n     * Remove a plugin from the registry.\n     * \n     * @param plugin The plugin to remove.\n     */\n    public void removePlugin(Plugin plugin) {\n        GSTREGISTRY_API.gst_registry_remove_plugin(this, plugin);\n    }\n    \n//    /**\n//     * Find the {@link PluginFeature} with the given name and type in the registry.\n//     * \n//     * @param name The name of the plugin feature to find.\n//     * @param type The type of the plugin feature to find.\n//     * @return The pluginfeature with the given name and type or null\n//     * if the plugin was not found.\n//     */\n//    public PluginFeature findPluginFeature(String name, GType type) {\n//        return GSTREGISTRY_API.gst_registry_find_feature(this, name, type);\n//    }\n    \n    /**\n     * Find a {@link PluginFeature} by name in the registry.\n     *\n     * @param name The name of the plugin feature to find.\n     * @return The {@link PluginFeature} or null if not found.\n     */\n    public PluginFeature lookupFeature(String name) {\n        return GSTREGISTRY_API.gst_registry_lookup_feature(this, name);\n    }\n    \n    /**\n     * Get a list of all plugins registered in the registry. \n     *\n     * @return a List of {@link Plugin}\n     */\n    public List<Plugin> getPluginList() {\n\n        GList glist = GSTREGISTRY_API.gst_registry_get_plugin_list(this);      \n        List<Plugin> list = objectList(glist, Plugin.class);\n        GSTPLUGIN_API.gst_plugin_list_free(glist);\n        return list;\n    }\n    \n    /**\n     * Get a subset of the Plugins in the registry, filtered by filter.\n     * \n     * @param filter the filter to use\n     * @return A List of {@link Plugin} objects that match the filter.\n     */\n    public List<Plugin> getPluginList(final PluginFilter filter) {\n        return getPluginList().stream().filter(filter::accept).collect(Collectors.toList());\n    }\n    \n//    /**\n//     * Retrieves a list of {@link PluginFeature} of the {@link Plugin} type.\n//     * \n//     * @param type The plugin type.\n//     * @return a List of {@link PluginFeature} for the plugin type.\n//     */\n//    public List<PluginFeature> getPluginFeatureListByType(GType type) {\n//        GList glist = GSTREGISTRY_API.gst_registry_get_feature_list(this, type);\n//        List<PluginFeature> list = objectList(glist, PluginFeature.class);\n//        GSTPLUGINFEATURE_API.gst_plugin_feature_list_free(glist);\n//        return list;\n//    }\n    \n    /**\n     * Retrieves a list of {@link PluginFeature} of the named {@link Plugin}.\n     * \n     * @param name The plugin name.\n     * @return a List of {@link PluginFeature} for the named plugin.\n     */\n    public List<PluginFeature> getPluginFeatureListByPlugin(String name) {\n        GList glist = GSTREGISTRY_API.gst_registry_get_feature_list_by_plugin(this, name);\n        List<PluginFeature> list = objectList(glist, PluginFeature.class);\n        GSTPLUGINFEATURE_API.gst_plugin_feature_list_free(glist);\n        return list;\n    }\n    \n    /**\n     * Add the given path to the registry. The syntax of the\n     * path is specific to the registry. If the path has already been\n     * added, do nothing.\n     *\n     * @param path The path to add to the registry.\n     * @return true if the registry changed.\n     */\n    public boolean scanPath(String path) {\n        return GSTREGISTRY_API.gst_registry_scan_path(this, path);\n    }\n    \n    /**\n     * Build a {@link java.util.List} of {@link GstObject} from the native GList.\n     * @param glist The native list to get the objects from.\n     * @param objectClass The proxy class to wrap the list elements in.\n     * @return The converted list.\n     */\n    private <T extends GstObject> List<T> objectList(GList glist, Class<T> objectClass) {\n        List<T> list = new ArrayList<T>();\n        GList next = glist;\n        while (next != null) {\n            if (next.data != null) {\n                list.add(Natives.objectFor(next.data, objectClass, true, true));\n            }\n            next = next.next();   \n        }\n        return list;\n    }\n    \n    public static interface PluginFilter {\n        public boolean accept(Plugin plugin);\n    }\n    \n//    public static interface PluginFeatureFilter {\n//        public boolean accept(PluginFeature feature);\n//    }\n//    \n    /**\n     * Retrieves the default registry. \n     * \n     * @return The default Registry.\n     */\n    public static Registry get() {\n        // Need to handle the return value here, as it is a persistent object\n        // i.e. the java proxy should not dispose of the underlying object when finalized\n        return Natives.objectFor(GSTREGISTRY_API.gst_registry_get(), Registry.class,\n                false, false);\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/SDPMessage.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2018 Antonio Morales\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport java.nio.charset.StandardCharsets;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstSDPMessageAPI.GSTSDPMESSAGE_API;\n\nimport org.freedesktop.gstreamer.glib.NativeObject;\n\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.lowlevel.GPointer;\n\n/**\n * Wrapping type and helper methods for dealing with SDP messages.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-libs/html/gst-plugins-base-libs-GstSDPMessage.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-libs/html/gst-plugins-base-libs-GstSDPMessage.html</a>\n */\npublic class SDPMessage extends NativeObject {\n    public static final String GTYPE_NAME = \"GstSDPMessage\";\n\n    /**\n     * Internally used constructor. Do not use.\n     *\n     * @param init internal initialization data\n     */\n    SDPMessage(Initializer init) {\n        this(new Handle(init.ptr, init.ownsHandle));\n    }\n\n    SDPMessage(Handle handle) {\n        super(handle);\n    }\n    \n    /**\n     * Creates a new instance of SDPMessage\n     */\n    public SDPMessage() {\n        this(initHandle());\n    }\n    \n    /**\n     * A SDP formatted string representation of SDPMessage.\n     *\n     * Used for offer/answer exchanges for real time communicationse\n     *\n     * @return the SDP string representation of SDPMessage.\n     */\n    public String toString() {\n        return GSTSDPMESSAGE_API.gst_sdp_message_as_text(this);\n    }\n\n    /**\n     * Takes a SDP string and parses it and fills in all fields for SDPMessage.\n     *\n     * Look at https://tools.ietf.org/html/rfc4566 for more information on SDP\n     *\n     * @param sdpString the sdp string\n     */\n    public void parseBuffer(String sdpString) {\n        byte[] data = sdpString.getBytes(StandardCharsets.US_ASCII);\n        int length = sdpString.length();\n        GSTSDPMESSAGE_API.gst_sdp_message_parse_buffer(data, length, this);\n    }\n\n//    /**\n//     * Creates a copy of this SDPMessage.\n//     *\n//     * @return a copy of SDPMessage.\n//     */\n//    SDPMessage copy(boolean shouldInvalidateOriginal) {\n//        Pointer[] ptr = new Pointer[1];\n//        GSTSDPMESSAGE_API.gst_sdp_message_copy(this, ptr);\n//        if (shouldInvalidateOriginal) {\n//            this.invalidate();\n//        }\n//        return new SDPMessage(initializer(ptr[0]));\n//    }\n\n    private static Handle initHandle() {\n        Pointer[] ptr = new Pointer[1];\n        GSTSDPMESSAGE_API.gst_sdp_message_new(ptr);\n        return new Handle(new GPointer(ptr[0]), true);\n    }\n\n    private static final class Handle extends NativeObject.Handle {\n\n        public Handle(GPointer ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n\n        @Override\n        protected void disposeNativeHandle(GPointer ptr) {\n            GSTSDPMESSAGE_API.gst_sdp_message_free(ptr.getPointer());\n        }\n        \n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/SDPResult.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2018 Antonio Morales\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.NativeEnum;\nimport org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue;\n\n/**\n * Return values for SDP functions\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-libs/html/gst-plugins-base-libs-GstSDPMessage.html#GstSDPResult\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-libs/html/gst-plugins-base-libs-GstSDPMessage.html#GstSDPResult</a>\n * \n * @see SDPMessage\n */\npublic enum SDPResult implements NativeEnum<SDPResult> {\n    /** A successful return value*/\n    OK(0),\n    /** A function to SDPMessage was given invalid parameters */\n    @DefaultEnumValue\n    EINVAL(-1);\n\n    private final int value;\n    \n    SDPResult(int value) {\n        this.value = value;\n    }\n\n    /**\n     * Gets the integer value of the enum\n     * @return the integer value for this enum.\n     */\n    @Override\n    public int intValue() {\n        return value;\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/Sample.java",
    "content": "/* \n * Copyright (c) 2020 Christophe Lafolet\n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2014 Tom Greenwood <tgreenwood@cafex.com>\n * Copyright (c) 2007, 2008 Wayne Meissner\n * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstSampleAPI.GSTSAMPLE_API;\n\n/**\n * A Sample is a small object containing data, a type, timing and extra\n * arbitrary information.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstSample.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstSample.html</a>\n *\n */\npublic class Sample extends MiniObject {\n\n    public static final String GTYPE_NAME = \"GstSample\";\n\n    Sample(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Get the {@link Caps} associated with sample, or NULL when there is no caps. \n     * <b>The caps remains valid as long as sample is valid.</b>\n     * If you need to hold on to the caps for longer than that, take a ref to the caps \n     *\n     * @return caps of sample or NULL when there is no caps.\n     */\n    public Caps getCaps() {\n        return GSTSAMPLE_API.gst_sample_get_caps(this);\n    }\n    \n    /**\n     * Set the {@link Caps} associated with sample. \n     * This sample must be writable.\n     * \n     * Since GStreamer 1.16\n     * \n     * @param caps\n     */\n    @Gst.Since(minor = 16)\n    public void setCaps(Caps caps) {\n    \tGst.checkVersion(1, 16);\n    \tGSTSAMPLE_API.gst_sample_set_caps(this, caps);\n    }\n\n    /**\n     * Get the {@link Buffer} associated with sample, or NULL when there is no\n     * buffer.\n     * <b>The buffer remains valid as long as sample is valid.</b>\n     * If you need to hold on to it for longer than that, take a ref to the buffer.\n     *\n     * @return buffer of sample or NULL when there is no buffer.\n     */\n    public Buffer getBuffer() {\n        return GSTSAMPLE_API.gst_sample_get_buffer(this);\n    }\n    \n    /**\n     * Set the {@link Buffer} associated with sample. \n     * This sample must be writable.\n     * \n     * Since GStreamer 1.16\n     * \n     * @param buffer\n     */\n    @Gst.Since(minor = 16)\n    public void setBuffer(Buffer buffer) {\n    \tGst.checkVersion(1, 16);\n    \tGSTSAMPLE_API.gst_sample_set_buffer(this, buffer);\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/Segment.java",
    "content": "/*\n * Copyright (c) 2010 David Hoyt <dhoyt@hoytsoft.org>\n * Copyright (c) 2010 David Hoyt <dhoyt@hoytsoft.org>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\n/**\n * A representation of the values used in querying the pipeline using\n * gst_query_new_segment() and subsequently gst_query_parse_segment().\n */\npublic final class Segment {\n    //--------------------------------------------------------------------------\n    // Instance variables\n    //\n    private final double rate;\n    private final Format format;\n    private final long startValue;\n    private final long stopValue;\n\n   /**\n    * Creates a new instance of {@link Segment}.\n    *\n    * @param rate the rate of the segment.\n    * @param format the {@link Format} of the segment values.\n    * @param startValue the start value.\n    * @param stopValue the stop value.\n    */\n    Segment(double rate, Format format, long startValue, long stopValue) {\n        this.rate = rate;\n        this.format = format;\n        this.stopValue = stopValue;\n        this.startValue = startValue;\n    }\n\n    /**\n     * Gets the rate of the segment.\n     *\n     * @return The rate of the segment.\n     */\n    public double getRate() {\n        return rate;\n    }\n\n    /**\n     * Gets the {@link Format} of the segment values.\n     *\n     * @return The {@link Format} of the segment values.\n     */\n    public Format getFormat() {\n        return format;\n    }\n\n    /**\n     * Gets the start value.\n     * \n     * @return The start value.\n     */\n    public long getStartValue() {\n        return startValue;\n    }\n\n    /**\n     * Gets the stop value.\n     * \n     * @return The stop value.\n     */\n    public long getStopValue() {\n        return stopValue;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/SegmentFlags.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.event.SeekFlags;\nimport org.freedesktop.gstreamer.glib.NativeFlags;\n\n/**\n * GstSegmentFlags\n */\nenum SegmentFlags implements NativeFlags<SegmentFlags> {\n\n//    /**\n//     * no flags\n//     */\n//    public static final int NONE = SeekFlags.NONE;\n    /**\n     * reset the pipeline running_time to the segment running_time\n     */\n    RESET(SeekFlags.FLUSH),\n    \n    /**\n     * perform skip playback\n     */\n    TRICKMODE(SeekFlags.TRICKMODE),\n    /**\n     * send SEGMENT_DONE instead of EOS\n     */\n    SEGMENT(SeekFlags.SEGMENT),\n    /**\n     * Decode only keyframes, where possible\n     */\n    TRICKMODE_KEY_UNITS(SeekFlags.TRICKMODE_KEY_UNITS),\n    /**\n     * Do not decode any audio, where possible (Since 1.6)\n     */\n    TRICKMODE_NO_AUDIO(SeekFlags.TRICKMODE_NO_AUDIO);\n\n    private final SeekFlags seekFlags;\n    \n    private SegmentFlags(SeekFlags seekFlags) {\n        this.seekFlags = seekFlags;\n    }\n\n    @Override\n    public int intValue() {\n        return seekFlags.intValue();\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/State.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.NativeEnum;\n//import org.freedesktop.gstreamer.lowlevel.EnumMapper;\n\n/**\n * The possible states an element can be in.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstElement.html#GstState\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstElement.html#GstState</a>\n * <p>\n */\npublic enum State implements NativeEnum<State> {\n    /**\n     * No pending state.\n     */\n    VOID_PENDING(0),\n    /**\n     * The initial state of an {@link Element}.\n     */\n    NULL(1),\n    /**\n     * The {@link Element} is ready to go to PAUSED.\n     */\n    READY(2),\n    /**\n     * The {@link Element} is PAUSED\n     */\n    PAUSED(3),\n    /**\n     * The {@link Element} is PLAYING\n     */\n    PLAYING(4);\n\n    private final int value;\n    \n    private State(int value) {\n        this.value = value;\n    }\n\n    /**\n     * Gets the integer value of the enum.\n     *\n     * @return The integer value for this enum.\n     */\n    @Override\n    public int intValue() {\n        return value;\n    }\n\n//    /**\n//     * Returns the enum constant of this type with the specified integer value.\n//     *\n//     * @param state integer value.\n//     * @return Enum constant.\n//     * @throws java.lang.IllegalArgumentException if the enum type has no\n//     * constant with the specified value.\n//     */\n//    public static final State valueOf(int state) {\n//        return EnumMapper.getInstance().valueOf(state, State.class);\n//    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/StateChangeReturn.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.NativeEnum;\n\n/**\n * The possible return values from a state change function. \n * <p>\n * Only {@link StateChangeReturn#FAILURE} is a real failure.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstElement.html#GstStateChangeReturn\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstElement.html#GstStateChangeReturn</a>\n * <p>\n */\npublic enum StateChangeReturn implements NativeEnum<StateChangeReturn> {\n    /** The state change failed. */\n    FAILURE(0),\n    /** The state change succeeded. */\n    SUCCESS(1),\n    /** The state change will happen asynchronously. */\n    ASYNC(2),\n    /**\n     * The state change succeeded but the {@link Element} cannot produce data in \n     * {@link State#PAUSED}. This typically happens with live sources.\n     */\n    NO_PREROLL(3);\n    \n    private final int value;\n    \n    private StateChangeReturn(int value) {\n        this.value = value;\n    }\n\n    @Override\n    public int intValue() {\n        return value;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/StaticPadTemplate.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\npublic class StaticPadTemplate {\n\n    private final String templateName;\n    private final PadDirection direction;\n    private final PadPresence presence;\n    private final Caps caps;\n\n    StaticPadTemplate(String templateName, PadDirection direction, PadPresence presence,\n            Caps caps) {\n        this.templateName = templateName;\n        this.direction = direction;\n        this.presence = presence;\n        this.caps = caps;\n    }\n\n    /**\n     * Get the name of the template.\n     *\n     * @return The name of the template.\n     */\n    public String getName() {\n        return templateName;\n    }\n\n    /**\n     * Get the direction (SINK, SRC) of the template.\n     *\n     * @return The {@link PadDirection} of the template.\n     */\n    public PadDirection getDirection() {\n        return direction;\n    }\n\n    /**\n     * Get the presence (ALWAYS, SOMETIMES, REQUEST) of the template.\n     *\n     * @return The {@link PadPresence} of this template.\n     */\n    public PadPresence getPresence() {\n        return presence;\n    }\n\n    /**\n     * Get the {@link Caps} of the template.\n     *\n     * @return The {@link Caps} for this template.\n     */\n    public Caps getCaps() {\n        return caps;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/Structure.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (C) 2009 Tamas Korodi <kotyo@zamba.fm> \n * Copyright (C) 2007 Wayne Meissner\n * Copyright (C) 2003 David A. Schleef <ds@schleef.org>\n * \n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport com.sun.jna.Pointer;\nimport com.sun.jna.ptr.PointerByReference;\n\nimport org.freedesktop.gstreamer.glib.GObject;\nimport org.freedesktop.gstreamer.glib.NativeObject;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GPointer;\nimport org.freedesktop.gstreamer.lowlevel.GType;\nimport org.freedesktop.gstreamer.lowlevel.GValueAPI;\nimport org.freedesktop.gstreamer.lowlevel.GValueAPI.GValue;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstStructureAPI.GSTSTRUCTURE_API;\nimport static org.freedesktop.gstreamer.lowlevel.GstValueAPI.GSTVALUE_API;\n\n/**\n * Generic structure containing fields of names and values.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstStructure.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstStructure.html</a>\n * <p>\n * A Structure is a collection of key/value pairs. The keys are expressed as\n * GQuarks and the values can be of any GType.\n * <p>\n * In addition to the key/value pairs, a Structure also has a name. The name\n * starts with a letter and can be followed by letters, numbers and any of\n * \"/-_.:\".\n * <p>\n * Structure is used by various GStreamer subsystems to store information in a\n * flexible and extensible way.\n * <p>\n * A Structure can be created with new {@link #Structure(String)} or\n * {@link #Structure(String, String, Object...)}, which both take a name and an\n * optional set of key/value pairs along with the types of the values.\n * <p>\n * Field values can be changed with set{Integer,String}() etc functions.\n * <p>\n * Field values can be retrieved with get{Integer,String}() etc functions.\n * <p>\n * Fields can be removed with {@link #removeField} or {@link #removeFields}\n *\n * @see Caps\n * @see Event\n */\npublic class Structure extends NativeObject {\n    \n    public static final String GTYPE_NAME = \"GstStructure\";\n\n    /**\n     * Creates a new, empty #GstStructure with the given name.\n     *\n     * @param name The name of new structure.\n     */\n    public Structure(String name) {\n        this(new Handle(new GPointer(GSTSTRUCTURE_API.ptr_gst_structure_new_empty(name)), true));\n    }\n\n    /**\n     * Creates a new Structure with the given name. Parses the list of variable\n     * arguments and sets fields to the values listed. Variable arguments should\n     * be passed as field name, field type, and value.\n     *\n     * @param name The name of new structure.\n     * @param firstFieldName The name of first field to set\n     * @param data Additional arguments.\n     */\n    public Structure(String name, String firstFieldName, Object... data) {\n        this(new Handle(new GPointer(GSTSTRUCTURE_API.ptr_gst_structure_new(name, firstFieldName, data)), true));\n    }\n    /**\n     * Creates a new instance of Structure\n     */\n    Structure(Initializer init) {\n        this(new Handle(init.ptr, init.ownsHandle));\n    }\n    \n    private Structure(Handle handle) {\n        super(handle);\n    }\n\n    public Structure copy() {\n        return GSTSTRUCTURE_API.gst_structure_copy(this);\n    }\n\n    public boolean fixateNearestInteger(String field, Integer value) {\n        return GSTSTRUCTURE_API.gst_structure_fixate_field_nearest_int(this, field, value);\n    }\n    /**\n     * Get the value of the named field as a boolean. Throws\n     * {@link InvalidFieldException} if the Structure does not contain the named\n     * field or the named field is not a boolean.\n     *\n     * @param fieldName name of field\n     * @return boolean value of the named field\n     */\n    public boolean getBoolean(String fieldName) {\n        int[] val = {0};\n        if (!GSTSTRUCTURE_API.gst_structure_get_boolean(this, fieldName, val)) {\n            throw new InvalidFieldException(\"boolean\", fieldName);\n        }\n        return val[0] != 0;\n    }\n\n    /**\n     * Get the value of the named field as a double. Throws\n     * {@link InvalidFieldException} if the Structure does not contain the named\n     * field or the named field is not a double.\n     *\n     * @param fieldName name of field\n     * @return double value of the named field\n     */\n    public double getDouble(String fieldName) {\n        double[] val = {0d};\n        if (!GSTSTRUCTURE_API.gst_structure_get_double(this, fieldName, val)) {\n            throw new InvalidFieldException(\"double\", fieldName);\n        }\n        return val[0];\n    }\n\n    /**\n     * Extract the values of the named field as an array of doubles. If the\n     * native GType of the field is a GValueArray then this method will return\n     * an array of the contained values, assuming all contained values are of\n     * G_TYPE_DOUBLE. Else if the field is of G_TYPE_DOUBLE a single value array\n     * will be returned.\n     * <p>\n     * This method will create a new array each time. If you are repeatedly\n     * calling this method consider using\n     * {@link #getDoubles(java.lang.String, double[])}.\n     * <p>\n     * Throws {@link InvalidFieldException} if the field does not exist, or the\n     * field values contained are not of type G_TYPE_DOUBLE.\n     * <p>\n     * This method only currently supports lists of values inside a GValueArray\n     * - other native list types will be supported in future.\n     *\n     * @param fieldName name of field\n     * @return List of values from the named field\n     */\n    public double[] getDoubles(String fieldName) {\n        return getDoubles(fieldName, null);\n    }\n\n    /**\n     * Extract the values of the named field as an array of doubles. If the\n     * native GType of the field is a GValueArray then this method will return\n     * an array of the contained values, assuming all contained values are of\n     * G_TYPE_DOUBLE. Else if the field is of G_TYPE_DOUBLE a single value array\n     * will be returned.\n     * <p>\n     * An array may be passed into this method to contain the result. A new\n     * array will be created if the array is null or not of the correct length.\n     * <p>\n     * Throws {@link InvalidFieldException} if the field does not exist, or the\n     * field values contained are not of type G_TYPE_DOUBLE.\n     * <p>\n     * This method only currently supports lists of values inside a GValueArray\n     * - other native list types will be supported in future.\n     *\n     * @param fieldName name of field\n     * @param array an array to hold values, or null\n     * @return List of values from the named field\n     */\n    public double[] getDoubles(String fieldName, double[] array) {\n        Object val = getValue(fieldName);\n        if (val instanceof GValueAPI.GValueArray) {\n            GValueAPI.GValueArray arr = (GValueAPI.GValueArray) val;\n            int count = arr.getNValues();\n            double[] values = array == null || array.length != count\n                    ? new double[count] : array;\n            for (int i = 0; i < count; i++) {\n                GValue gval = arr.nth(i);\n                if (gval.checkHolds(GType.DOUBLE)) {\n                    values[i] = GValueAPI.GVALUE_API.g_value_get_double(gval);\n                } else {\n                    throw new InvalidFieldException(\"doubles\", fieldName);\n                }\n            }\n            return values;\n        } else {\n            if (Double.class.isInstance(val)) {\n                double[] values = array == null || array.length != 1\n                        ? new double[1] : array;\n                values[0] = ((Double) val);\n                return values;\n            } else {\n                throw new InvalidFieldException(\"double\", fieldName);\n            }\n        }\n    }\n\n    /**\n     * Get the number of fields in the {@link Structure}.\n     *\n     * @return the structure's filed number.\n     */\n    public int getFields() {\n        return GSTSTRUCTURE_API.gst_structure_n_fields(this);\n    }\n\n\n    /**\n     * Gets FOURCC field int representation\n     *\n     * @param fieldName The name of the field.\n     * @return FOURCC field as a 4 byte integer\n     */\n    public int getFourcc(String fieldName) {\n        int[] val = {0};\n        if (!GSTSTRUCTURE_API.gst_structure_get_fourcc(this, fieldName, val)) {\n            throw new InvalidFieldException(\"FOURCC\", fieldName);\n        }\n        return val[0];\n    }\n\n    /**\n     * Gets FOURCC field String representation\n     *\n     * @param fieldName The name of the field.\n     * @return FOURCC field as a String\n     */\n    public String getFourccString(String fieldName) {\n        int f = getFourcc(fieldName);\n        byte[] b = {(byte) ((f >> 0) & 0xff), (byte) ((f >> 8) & 0xff),\n            (byte) ((f >> 16) & 0xff), (byte) ((f >> 24) & 0xff)};\n        return new String(b);\n    }\n    \n    /**\n     * Get the value of the named field as a Fraction. Throws\n     * {@link InvalidFieldException} if the Structure does not contain the named\n     * field or the named field is not a Fraction.\n     *\n     * @param fieldName name of field\n     * @return boolean value of the named field\n     */\n    public Fraction getFraction(String fieldName) {\n        int[] numerator = {0};\n        int[] denominator = {0};\n        if (!GSTSTRUCTURE_API.gst_structure_get_fraction(this, fieldName, numerator, denominator)) {\n            throw new InvalidFieldException(\"fraction\", fieldName);\n        }\n        return new Fraction(numerator[0], denominator[0]);\n    }\n    /**\n     * Get the value of the named field as an int. Throws\n     * {@link InvalidFieldException} if the Structure does not contain the named\n     * field or the named field is not an integer.\n     *\n     * @param fieldName name of field\n     * @return int value of the named field\n     */\n    public int getInteger(String fieldName) {\n        int[] val = {0};\n        if (!GSTSTRUCTURE_API.gst_structure_get_int(this, fieldName, val)) {\n            throw new InvalidFieldException(\"integer\", fieldName);\n        }\n        return val[0];\n    }\n\n    /**\n     * Extract the values of the named field as an array of integers. If the\n     * native GType of the field is a GValueArray then this method will return\n     * an array of the contained values, assuming all contained values are of\n     * G_TYPE_INT. Else if the field is of G_TYPE_INT a single value array will\n     * be returned.\n     * <p>\n     * This method will create a new array each time. If you are repeatedly\n     * calling this method consider using\n     * {@link #getIntegers(java.lang.String, int[])}.\n     * <p>\n     * Throws {@link InvalidFieldException} if the field does not exist, or the\n     * field values contained are not of type G_TYPE_INT.\n     * <p>\n     * This method only currently supports lists of values inside a GValueArray\n     * - other native list types will be supported in future.\n     *\n     * @param fieldName name of field\n     * @return List of values from the named field\n     */\n    public int[] getIntegers(String fieldName) {\n        return getIntegers(fieldName, null);\n    }\n    /**\n     * Extract the values of the named field as an array of integers. If the\n     * native GType of the field is a GValueArray then this method will return\n     * an array of the contained values, assuming all contained values are of\n     * G_TYPE_INT. Else if the field is of G_TYPE_INT a single value array will\n     * be returned.\n     * <p>\n     * An array may be passed into this method to contain the result. A new\n     * array will be created if the array is null or not of the correct length.\n     * <p>\n     * Throws {@link InvalidFieldException} if the field does not exist, or the\n     * field values contained are not of type G_TYPE_INT.\n     * <p>\n     * This method only currently supports lists of values inside a GValueArray\n     * - other native list types will be supported in future.\n     *\n     * @param fieldName name of field\n     * @param array an array to hold values, or null\n     * @return List of values from the named field\n     */\n    public int[] getIntegers(String fieldName, int[] array) {\n        Object val = getValue(fieldName);\n        if (val instanceof GValueAPI.GValueArray) {\n            GValueAPI.GValueArray arr = (GValueAPI.GValueArray) val;\n            int count = arr.getNValues();\n            int[] values = array == null || array.length != count\n                    ? new int[count] : array;\n            for (int i = 0; i < count; i++) {\n                GValue gval = arr.nth(i);\n                if (gval.checkHolds(GType.INT)) {\n                    values[i] = GValueAPI.GVALUE_API.g_value_get_int(gval);\n                } else {\n                    throw new InvalidFieldException(\"integers\", fieldName);\n                }\n            }\n            return values;\n        } else {\n            if (Integer.class.isInstance(val)) {\n                int[] values = array == null || array.length != 1\n                        ? new int[1] : array;\n                values[0] = ((Integer) val);\n                return values;\n            } else {\n                throw new InvalidFieldException(\"integer\", fieldName);\n            }\n        }\n    }\n\n    /**\n     * Sets the name of the structure to the given name.\n     *\n     * The name must not be empty, must start with a letter and can be followed\n     * by letters, numbers and any of \"/-_.:\".\n     *\n     * @param name The new name of the structure.\n     */\n    public void setName(String name) {\n        GSTSTRUCTURE_API.gst_structure_set_name(this, name);\n    }\n\n    /**\n     * Get the name of @structure as a string.\n     *\n     * @return The name of the structure.\n     */\n    public String getName() {\n        return GSTSTRUCTURE_API.gst_structure_get_name(this);\n    }\n    \n    /**\n     * Get the @structure's ith field name as a string.\n     *\n     * @param i the requested filed number\n     * @return The name of the structure.\n     */\n    public String getName(int i) {\n        return GSTSTRUCTURE_API.gst_structure_nth_field_name(this, i);\n    }\n\n    /**\n     * Get the value of the named field as a Range. Throws\n     * {@link InvalidFieldException} if the Structure does not contain the named\n     * field.\n     *\n     * @param fieldName name of field\n     * @return Range value of the named field\n     */\n    public Range getRange(String fieldName) {\n        GValue val = GSTSTRUCTURE_API.gst_structure_get_value(this, fieldName);\n        if (val == null) {\n            throw new InvalidFieldException(\"Range\", fieldName);\n        }\n        return new Range(val);\n    }\n    /**\n     * Get the value of the named field as a String.\n     *\n     * @param fieldName name of field\n     * @return String value of the named field\n     */\n    public String getString(String fieldName) {\n        return GSTSTRUCTURE_API.gst_structure_get_string(this, fieldName);\n    }\n    \n    /**\n     * Get the value of the named field. Throws {@link InvalidFieldException} if\n     * the Structure does not contain the named field.\n     *\n     * @param fieldName name of field\n     * @return Object representation of the named field\n     */\n    public Object getValue(String fieldName) {\n        GValue val = GSTSTRUCTURE_API.gst_structure_get_value(this, fieldName);\n        \n        if (val == null) {\n            throw new InvalidFieldException(\"Object\", fieldName);\n        }\n\n        return val.getValue();\n    }\n\n    /**\n     * Extract the values of the named field as a List of the provided type. If\n     * the native GType of the field is a GValueArray then this method will\n     * return a list of the contained values, assuming all contained values can\n     * be converted to the provided Java type T. Else if the field GType can be\n     * directly converted to the provided Java type T, a singleton List will be\n     * returned.\n     * <p>\n     * Throws {@link InvalidFieldException} if the field does not exist, or the\n     * field values cannot be converted to type T.\n     * <p>\n     * This method currently supports lists of values inside a GValueArray or\n     * GstValueList.\n     *\n     * @param <T>\n     * @param type type of values\n     * @param fieldName name of field\n     * @return List of values from the named field\n     */\n    public <T> List<T> getValues(Class<T> type, String fieldName) {\n        GValue gValue = GSTSTRUCTURE_API.gst_structure_get_value(this, fieldName);\n        if (gValue == null) {\n            throw new InvalidFieldException(type.getSimpleName(), fieldName);\n        }\n\n        GType gType = gValue.getType();\n        if (gType.equals(GSTVALUE_API.gst_value_list_get_type())) {\n            int size = GSTVALUE_API.gst_value_list_get_size(gValue);\n            ArrayList<T> values = new ArrayList<>(size);\n            for (int i = 0; i <size; i++) {\n                Object o = GSTVALUE_API.gst_value_list_get_value(gValue, i).getValue();\n                if (type.isInstance(o)) {\n                    values.add(type.cast(o));\n                } else {\n                    throw new InvalidFieldException(type.getSimpleName(), fieldName);\n                }\n            }\n\n            return values;\n        }\n\n        Object val = gValue.getValue();\n        if (val instanceof GValueAPI.GValueArray) {\n            GValueAPI.GValueArray arr = (GValueAPI.GValueArray) val;\n            int count = arr.getNValues();\n            List<T> values = new ArrayList<T>(count);\n            for (int i = 0; i < count; i++) {\n                Object o = arr.getValue(i);\n                if (type.isInstance(o)) {\n                    values.add(type.cast(o));\n                } else {\n                    throw new InvalidFieldException(type.getSimpleName(), fieldName);\n                }\n            }\n            return values;\n        } else {\n            if (type.isInstance(val)) {\n                return Collections.singletonList(type.cast(val));\n            } else {\n                throw new InvalidFieldException(type.getSimpleName(), fieldName);\n            }\n        }\n    }\n    \n    /**\n     * Check if the {@link Structure} contains a double field named fieldName.\n     *\n     * @param fieldName The name of the field to check.\n     * @return true if the structure contains a double field named fieldName\n     */\n    public boolean hasDoubleField(String fieldName) {\n        return hasField(fieldName, GType.DOUBLE);\n    }\n\n    /**\n     * Check if the {@link Structure} contains a field named fieldName.\n     *\n     * @param fieldName The name of the field to check.\n     * @return true if the structure contains a field with the given name.\n     */\n    public boolean hasField(String fieldName) {\n        return GSTSTRUCTURE_API.gst_structure_has_field(this, fieldName);\n    }\n\n\n    /**\n     * Check if the {@link Structure} contains a field named fieldName.\n     *\n     * @param fieldName The name of the field to check.\n     * @param fieldType The type of the field.\n     * @return true if the structure contains a field named fieldName and of\n     * type fieldType\n     */\n    boolean hasField(String fieldName, GType fieldType) {\n        return GSTSTRUCTURE_API.gst_structure_has_field_typed(this, fieldName, fieldType);\n    }\n\n    /**\n     * Check if the {@link Structure} contains a field named fieldName.\n     *\n     * @param fieldName The name of the field to check.\n     * @param fieldType The type of the field.\n     * @return true if the structure contains a field named fieldName and of\n     * type fieldType\n     */\n    public boolean hasField(String fieldName, Class<?> fieldType) {\n        return GSTSTRUCTURE_API.gst_structure_has_field_typed(this, fieldName, GType.valueOf(fieldType));\n    }\n\n    /**\n     * Check if the {@link Structure} contains an integer field named fieldName.\n     *\n     * @param fieldName The name of the field to check.\n     * @return true if the structure contains an integer field named fieldName\n     */\n    public boolean hasIntField(String fieldName) {\n        return hasField(fieldName, GType.INT);\n    }\n    /**\n     * Checks if the structure has the given name.\n     *\n     * @param name structure name to check for\n     * @return true if @name matches the name of the structure.\n     */\n    public boolean hasName(String name) {\n        return GSTSTRUCTURE_API.gst_structure_has_name(this, name);\n    }\n    /**\n     * Checks that two structures are equal\n     *\n     * @param structure the structure to check if it's equal to this structure\n     * @return true if both structures are equal\n     */\n    public boolean isEqual(Structure structure) {\n        return GSTSTRUCTURE_API.gst_structure_is_equal(this, structure);\n    }\n\n    /**\n     * Removes the field with the given name from the structure. If the field\n     * with the given name does not exist, the structure is unchanged.\n     *\n     * @param fieldName The name of the field to remove.\n     */\n    public void removeField(String fieldName) {\n        GSTSTRUCTURE_API.gst_structure_remove_field(this, fieldName);\n    }\n\n    /**\n     * Removes the fields with the given names. If a field does not exist, the\n     * argument is ignored.\n     *\n     * @param fieldNames A list of field names to remove.\n     */\n    public void removeFields(String... fieldNames) {\n        GSTSTRUCTURE_API.gst_structure_remove_fields(this, fieldNames);\n    }\n    \n    public void setDouble(String field, Double value) {\n        GSTSTRUCTURE_API.gst_structure_set(this, field, GType.DOUBLE, value);\n    }\n    \n    public void setDoubleRange(String field, Double min, Double max) {\n        GSTSTRUCTURE_API.gst_structure_set(this, field,\n                GSTVALUE_API.gst_double_range_get_type(), min, max);\n    }\n    \n    public void setFraction(String field, Integer numerator, Integer denominator) {\n        GSTSTRUCTURE_API.gst_structure_set(this, field,\n                GSTVALUE_API.gst_fraction_get_type(), numerator, denominator);\n    }\n    /**\n     * Sets an integer field in the structure.\n     *\n     * @param field the name of the field to set.\n     * @param value the value to set for the field.\n     */\n    public void setInteger(String field, Integer value) {\n        GSTSTRUCTURE_API.gst_structure_set(this, field, GType.INT, value);\n    }\n    \n    public void setIntegerRange(String field, Integer min, Integer max) {\n        GSTSTRUCTURE_API.gst_structure_set(this, field,\n                GSTVALUE_API.gst_int_range_get_type(), min, max);\n    }\n    \n    /**\n     * Set an object field in the structure.\n     * \n     * @param field the name of the field to set.\n     * @param typeName a type into which the provided object could be coerced into.\n     * @param object the value to set for the field (must not be {@code null}).\n     */\n    public void setObject(String field, String typeName, GObject object) {\n        GType type = GType.valueOf(typeName);\n        if (!GType.INVALID.equals(type)) {\n            if (object != null) {\n                GType realType = GType.valueOf(object.getTypeName());\n                while (!realType.equals(GType.OBJECT) && !realType.equals(type)) {\n                    realType = realType.getParentType();\n                }\n                if (!realType.equals(type)) {\n                    throw new IllegalArgumentException(\n                            \"Provided instance of \" + object.getTypeName() + \" is not a \" + typeName);\n                }\n                setValue(field, type, object);\n            } else {\n                throw new IllegalArgumentException(\"Null object provided\");\n            }\n        } else {\n            throw new IllegalArgumentException(\"Unknown GType name: \" + typeName);\n        }\n    }\n\n    void setPointer(String field, Pointer value) {\n        GSTSTRUCTURE_API.gst_structure_set(this, field, GType.POINTER, value);\n    }\n    void setValue(String field, GType type, Object value) {\n        GSTSTRUCTURE_API.gst_structure_set(this, field, type, value);\n    }\n\n    @Override\n    public String toString() {\n        return GSTSTRUCTURE_API.gst_structure_to_string(this);\n    }\n\n    /**\n     * Creates a Structure from a string representation.\n     *\n     * @param data A string representation of a Structure.\n     * @return A new Structure or null when the string could not be parsed.\n     */\n    public static Structure fromString(String data) {\n        return new Structure(\n                new Handle(\n                        new GPointer(GSTSTRUCTURE_API.ptr_gst_structure_from_string(data, new PointerByReference()))\n                , true));\n    }\n    \n    static Structure objectFor(Pointer ptr, boolean needRef, boolean ownsHandle) {\n        return Natives.objectFor(ptr, Structure.class, needRef, ownsHandle);\n    }\n    \n    public class InvalidFieldException extends RuntimeException {\n        \n        private static final long serialVersionUID = 864118748304334069L;\n        \n        public InvalidFieldException(String type, String fieldName) {\n            super(String.format(\"Structure does not contain %s field '%s'\", type, fieldName));\n        }\n    }\n    \n    private static final class Handle extends NativeObject.Handle {\n\n        public Handle(GPointer ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n\n        @Override\n        protected void disposeNativeHandle(GPointer ptr) {\n            GSTSTRUCTURE_API.gst_structure_free(ptr.getPointer());\n        }\n        \n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/Tag.java",
    "content": "/* \n * Copyright (C) 2007 Wayne Meissner\n * Copyright (C) 2003 Benjamin Otte\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\n/**\n * GStreamer core tags\n */\nenum Tag {\n    /** \n     * The artist name as it should be displayed, e.g. 'Jimi Hendrix' or\n     * 'The Guitar Heroes'\n     */\n    ARTIST(\"artist\"),\n    /**\n     * The artist name as it should be sorted, e.g. 'Hendrix, Jimi' or\n     * 'Guitar Heroes, The'\n     */\n    ARTIST_SORTNAME(\"musicbrainz-sortname\"),\n    /** The title as it should be displayed, e.g. 'The Doll House' */\n    TITLE(\"title\"),\n    /** The title as it should be sorted, e.g. 'Doll House, The' */\n    TITLE_SORTNAME(\"title-sortname\"),\n    /** The album name as it should be displayed, e.g. 'The Jazz Guitar' */\n    ALBUM(\"album\"),\n    /** The album name as it should be sorted, e.g. 'Jazz Guitar, The' */\n    ALBUM_SORTNAME(\"album-sortname\"),\n    /** Person(s) who composed the recording */\n    COMPOSER(\"composer\"),\n    /** Genre of the media */\n    GENRE(\"genre\"),\n    COMMENT(\"comment\"),\n    EXTENDED_COMMENT(\"extended-comment\"),\n    /** Original location of file as a URI */\n    LOCATION(\"location\"),\n    /** Short text describing the content of the data */ \n    DESCRIPTION(\"description\"),\n    /** Version of this data */\n    VERSION(\"version\"),\n    /** Organization */\n    ORGANIZATION(\"organization\"),\n    /** Copyright notice for the data */\n    COPYRIGHT(\"copyright\"),\n    /** URI to location where copyright details can be found  */\n    COPYRIGHT_URI(\"copyright-uri\"),\n    /** Contact information */\n    CONTACT(\"contact\"),\n    /** License of data */\n    LICENSE(\"license\"),\n    /** URI to location where license details can be found */\n    LICENSE_URI(\"license-uri\"),\n    /** Person(s) performing */\n    PERFORMER(\"performer\"),\n    /** Codec the data is stored in  */\n    CODEC(\"codec\"),\n    /** Codec the audio data is stored in */\n    AUDIO_CODEC(\"audio-codec\"),\n    /** Codec the video data is stored in */\n    VIDEO_CODEC(\"video-codec\"),\n    /** Encoder used to encode this stream */\n    ENCODER(\"encoder\"),\n    /** Version of the encoder used to encode this stream */\n    ENCODER_VERSION(\"encoder-version\"),\n    /** Language code (ISO-639-1) String */\n    LANGUAGE_CODE(\"language-code\"),\n    /** Track number inside a collection. */\n    TRACK_NUMBER(\"track-number\"),\n    /** Count of tracks inside collection this track belongs to. */\n    TRACK_COUNT(\"track-count\"),\n    /** Disc number inside a collection. */\n    ALBUM_VOLUME_NUMBER(\"album-disc-number\"),\n    /** Count of discs inside collection this disc belongs to. */\n    ALBUM_VOLUME_COUNT(\"album-disc-count\"),\n    /** Exact or average bitrate in bits per second */\n    BITRATE(\"bitrate\"),\n    /** Nominal bitrate in bits/s */\n    NOMINAL_BITRATE(\"nominal-bitrate\"),\n    /** Minimum bitrate in bits/s */\n    MINIMUM_BITRATE(\"minimum-bitrate\"),\n    /** Maximum bitrate in bits/s */\n    MAXIMUM_BITRATE(\"maximum-bitrate\"),\n    /** Track gain in db */\n    TRACK_GAIN(\"replaygain-track-gain\"),\n    /** Peak of the track */\n    TRACK_PEAK(\"replaygain-track-peak\"),\n    /** Album gain in db */\n    ALBUM_GAIN(\"replaygain-album-gain\"),\n    /** Peak of the album */\n    ALBUM_PEAK(\"replaygain-album-peak\"),\n    /** Reference level of track and album gain values */\n    REFERENCE_LEVEL(\"replaygain-reference-level\"),\n    /** Serial number of track */\n    SERIAL(\"serial\"),\n    /** date the data was created */\n    DATE(\"date\"),\n    /** Length in GStreamer time units (nanoseconds) */\n    DURATION(\"duration\"),\n    ISRC(\"isrc\"),\n    /** Image */\n    IMAGE(\"image\"),\n    /** Image that is meant for preview purposes */\n    PREVIEW_IMAGE(\"preview-image\"),\n    /** Number of beats per minute in audio */\n    BEATS_PER_MINUTE(\"beats-per-minute\");\n    \n    Tag(String id) {\n        this.id = id;\n    }\n    public String getId() {\n        return id;\n    }    \n    private String id;\n\n   \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/TagFlag.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2007 Wayne Meissner\n * Copyright (C) 2003 Benjamin Otte\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.NativeEnum;\nimport org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue;\n\n/**\n * Extra tag flags used when registering tags.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstTagList.html#GstTagFlag\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstTagList.html#GstTagFlag</a>\n * <p>\n */\npublic enum TagFlag implements NativeEnum<TagFlag> {\n    /** Undefined flag. */\n    @DefaultEnumValue\n    UNDEFINED(0),\n    /** Tag is meta data. */\n    META(1),\n    /** Tag is encoded. */\n    ENCODED(2),\n    /** Tag is decoded. */\n    DECODED(3),\n    /** Number of tag flags. */\n    COUNT(4);\n    \n    private final int value;\n    \n    private TagFlag(int value) {\n        this.value = value;\n    }\n\n    @Override\n    public int intValue() {\n        return value;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/TagList.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2016 Christophe Lafolet\n * Copyright (c) 2014 Tom Greenwood <tgreenwood@cafex.com>\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport static org.freedesktop.gstreamer.lowlevel.GlibAPI.GLIB_API;\nimport static org.freedesktop.gstreamer.lowlevel.GstTagAPI.GSTTAG_API;\nimport static org.freedesktop.gstreamer.lowlevel.GstTagListAPI.GSTTAGLIST_API;\n\nimport java.util.AbstractList;\nimport java.util.HashMap;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport org.freedesktop.gstreamer.glib.GDate;\nimport org.freedesktop.gstreamer.lowlevel.GType;\nimport org.freedesktop.gstreamer.lowlevel.GstTagListAPI;\n\nimport com.sun.jna.Pointer;\nimport com.sun.jna.ptr.PointerByReference;\nimport org.freedesktop.gstreamer.glib.NativeObject;\nimport org.freedesktop.gstreamer.glib.Natives;\n\n/**\n * List of tags and values used to describe media metadata.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstTagList.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstTagList.html</a>\n * <p>\n */\n//@TODO consider handling Sample fields.\npublic class TagList extends MiniObject {\n\n    public static final String GTYPE_NAME = \"GstTagList\";\n    \n    /**\n     * Creates a new instance of TagList\n     *\n     * @param init internal initialization data.\n     */\n    TagList(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Constructs a new empty tag list.\n     */\n    public TagList() {\n        super(initializer());\n    }\n\n    private static Initializer initializer() {\n        final Pointer ptr_new_tag_list = GSTTAGLIST_API.ptr_gst_tag_list_new_empty();\n        return Natives.initializer(ptr_new_tag_list);\n    }\n\n    /**\n     * Gets the number of values of type {@code tag} stored in the list.\n     *\n     * @param tag the name of the tag to get the size of.\n     * @return the number of values for {@code tag} in this list.\n     */\n    public int getValueCount(String tag) {\n        return GSTTAGLIST_API.gst_tag_list_get_tag_size(this, tag);\n    }\n\n    /**\n     * Gets all data values for a tag contained in this list.\n     *\n     * @param tag the name of the tag to retrieve.\n     * @return the data associated with {@code tag}.\n     */\n    public List<Object> getValues(final String tag) {\n        final int size = getValueCount(tag);\n        return new AbstractList<Object>() {\n            public int size() {\n                return size;\n            }\n\n            @Override\n            public Object get(int index) {\n                return getValue(tag, index);\n            }\n        };\n    }\n\n//    /**\n//     * Gets all data values for a tag contained in this list.\n//     *\n//     * @param tag the name of the tag to retrieve.\n//     * @return the data associated with {@code tag}.\n//     */\n//    public List<Object> getValues(Tag tag) {\n//        return getValues(tag.getId());\n//    }\n\n    /**\n     * Gets data for a tag from this list.\n     *\n     * @param tag the tag to retrieve.\n     * @param index which element of the array of data for this tag to retrieve.\n     * @return the data for the tag.\n     */\n    public Object getValue(String tag, int index) {\n        TagGetter get = MapHolder.getterMap.get(getTagType(tag));\n        return get != null ? get.get(this, tag, index) : \"\";\n    }\n\n//    /**\n//     * Gets data for a tag from this list.\n//     *\n//     * @param tag the tag to retrieve.\n//     * @param index which element of the array of data for this tag to retrieve.\n//     * @return the data for the tag.\n//     */\n//    public Object getValue(Tag tag, int index) {\n//        return getValue(tag.getId(), index);\n//    }\n\n    /**\n     * Gets a string tag from this list.\n     *\n     * @param tag the tag to retrieve.\n     * @param index which element of the array of data for this tag to retrieve.\n     * @return the data for the tag.\n     */\n    public String getString(String tag, int index) {\n        return getValue(tag, index).toString();\n    }\n\n//    /**\n//     * Gets a string tag from this list.\n//     *\n//     * @param tag the tag to retrieve.\n//     * @param index which element of the array of data for this tag to retrieve.\n//     * @return the data for the tag.\n//     */\n//    public String getString(Tag tag, int index) {\n//        return getString(tag.getId(), index);\n//    }\n\n    /**\n     * Gets a numeric tag from this list.\n     *\n     * @param tag the tag to retrieve.\n     * @param index which element of the array of data for this tag to retrieve.\n     * @return the data for the tag.\n     */\n    public Number getNumber(String tag, int index) {\n        Object data = getValue(tag, index);\n        if (!(data instanceof Number)) {\n            throw new IllegalArgumentException(\"Tag [\" + tag + \"] is not a number\");\n        }\n        return (Number) data;\n    }\n\n//    /**\n//     * Gets a numeric tag from this list.\n//     *\n//     * @param tag the tag to retrieve.\n//     * @param index which element of the array of data for this tag to retrieve.\n//     * @return the data for the tag.\n//     */\n//    public Number getNumber(Tag tag, int index) {\n//        return getNumber(tag.getId(), index);\n//    }\n\n    /**\n     * Gets a list of all the tags contained in this list.\n     *\n     * @return a list of tag names.\n     */\n    public List<String> getTagNames() {\n        final List<String> list = new LinkedList<String>();\n        GSTTAGLIST_API.gst_tag_list_foreach(this, new GstTagListAPI.TagForeachFunc() {\n            public void callback(Pointer ptr, String tag, Pointer user_data) {\n                list.add(tag);\n            }\n        }, null);\n        return list;\n    }\n\n    /**\n     * Merges this tag list and {@code list2} into a new list. If {@code list2}\n     * is null, a copy of this list is returned.\n     *\n     * @param list2 the other tag list to merge with this one.\n     * @param mode the {@link TagMergeMode}.\n     * @return a new tag list.\n     */\n    public TagList merge(TagList list2, TagMergeMode mode) {\n        return GSTTAGLIST_API.gst_tag_list_merge(this, list2, mode);\n    }\n\n    /**\n     * Gets the low level type for the tag.\n     *\n     * @param tag the tag\n     * @return the type of {@code tag}\n     */\n    private static GType getTagType(String tag) {\n\n        GType type = MapHolder.tagTypeMap.get(tag);\n        if (type != null) {\n            return type;\n        }\n        MapHolder.tagTypeMap.put(tag, type = GSTTAG_API.gst_tag_get_type(tag));\n        return type;\n    }\n\n    private static interface TagGetter {\n\n        Object get(TagList tl, String tag, int index);\n    }\n\n    //\n    // Put the maps in a holder class so they don't get initialized until used.\n    // This helps avoid calling gstreamer methods before Gst.init().\n    //\n    private static final class MapHolder {\n\n        private static final Map<GType, TagGetter> getterMap = new HashMap<GType, TagGetter>() {\n            {\n                put(GType.INT, new TagGetter() {\n                    public Object get(TagList tl, String tag, int index) {\n                        int[] value = {0};\n                        GSTTAGLIST_API.gst_tag_list_get_int_index(tl, tag, index, value);\n                        return value[0];\n                    }\n                });\n                put(GType.UINT, new TagGetter() {\n                    public Object get(TagList tl, String tag, int index) {\n                        int[] value = {0};\n                        GSTTAGLIST_API.gst_tag_list_get_uint_index(tl, tag, index, value);\n                        return value[0];\n                    }\n                });\n                put(GType.INT64, new TagGetter() {\n                    public Object get(TagList tl, String tag, int index) {\n                        long[] value = {0};\n                        GSTTAGLIST_API.gst_tag_list_get_int64_index(tl, tag, index, value);\n                        return value[0];\n                    }\n                });\n                put(GType.DOUBLE, new TagGetter() {\n                    public Object get(TagList tl, String tag, int index) {\n                        double[] value = {0d};\n                        GSTTAGLIST_API.gst_tag_list_get_double_index(tl, tag, index, value);\n                        return value[0];\n                    }\n                });\n                put(GType.STRING, new TagGetter() {\n                    public Object get(TagList tl, String tag, int index) {\n                        Pointer[] value = {null};\n                        GSTTAGLIST_API.gst_tag_list_get_string_index(tl, tag, index, value);\n                        if (value[0] == null) {\n                            return null;\n                        }\n                        String ret = value[0].getString(0);\n                        GLIB_API.g_free(value[0]);\n                        return ret;\n                    }\n                });\n                put(GType.valueOf(GDate.GTYPE_NAME), new TagGetter() {\n                    public Object get(TagList tl, String tag, int index) {\n                        PointerByReference value = new PointerByReference();\n                        GSTTAGLIST_API.gst_tag_list_get_date_index(tl, tag, index, value);\n                        if (value.getValue() == null) {\n                            return null;\n                        }\n                        return Natives.objectFor(value.getValue(), GDate.class, false, true);\n                    }\n                });\n                put(GType.valueOf(DateTime.GTYPE_NAME), new TagGetter() {\n                    public Object get(TagList tl, String tag, int index) {\n                        PointerByReference value = new PointerByReference();\n                        GSTTAGLIST_API.gst_tag_list_get_date_time_index(tl, tag, index, value);\n                        if (value.getValue() == null) {\n                            return null;\n                        }\n                        return new DateTime(value.getValue(), false, true);\n                    }\n                });\n\n            }\n        };\n        static private final Map<String, GType> tagTypeMap = new ConcurrentHashMap<String, GType>();\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/TagMergeMode.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2007 Wayne Meissner\n * Copyright (C) 2003 Benjamin Otte\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.NativeEnum;\nimport org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue;\n\n/**\n * The different tag merging modes are basically replace, overwrite and append,\n * but they can be seen from two directions.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstTagList.html#GstTagMergeMode\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstTagList.html#GstTagMergeMode</a>\n * <p>\n * Given two taglists: A - the one that are supplied to\n * gst_tag_setter_merge_tags() or gst_tag_setter_add_tags() and B - the tags\n * already in the element, how are the tags merged? In the table below this is\n * shown for the cases that a tag exists in the list (A) or does not exists (!A)\n * and combination thereof.\n */\npublic enum TagMergeMode implements NativeEnum<TagMergeMode> {\n    /** Undefined merge mode. */\n    @DefaultEnumValue\n    UNDEFINED(0),\n    /** Replace all tags (clear list and append). */\n    REPLACE_ALL(1),\n    /** Replace tags */\n    REPLACE(2),\n    /** Append tags */\n    APPEND(3),\n    /** Prepend tags */\n    PREPEND(4),\n    /** Keep existing tags */\n    KEEP(5),\n    /** Keep all existing tags */\n    KEEP_ALL(6);\n\n    private final int value;\n    \n    private TagMergeMode(int value) {\n        this.value = value;\n    }\n    \n    @Override\n    public int intValue() {\n        return value;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/Version.java",
    "content": "/* \n * Copyright (c) 2021 Neil C Smith\n * Copyright (c) 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\n/**\n * Describes a GStreamer version.\n * <p>\n * Also upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/documentation/gstreamer/gst.html#gst_version\"\n * >https://gstreamer.freedesktop.org/documentation/gstreamer/gst.html#gst_version</a>\n * <p>\n */\npublic class Version {\n\n    /**\n     * The baseline version of GStreamer supported by these Java bindings.\n     * Currently GStreamer 1.8.\n     */\n    public static final Version BASELINE = new Version(1, 8);\n\n    private final int major, minor, micro, nano;\n\n    /**\n     * Constructor for creating a Version with micro and nano set to zero. For\n     * requesting version in {@link Gst#init(org.freedesktop.gstreamer.Version)}\n     * prefer using {@link #of(int, int)}.\n     * <p>\n     * <b>The library only supports major version 1</b>\n     *\n     * @param major Major version of GStreamer\n     * @param minor Minor version of GStreamer\n     */\n    public Version(int major, int minor) {\n        this(major, minor, 0, 0);\n    }\n\n    /**\n     * Constructor for creating a Version reflecting all aspects of the native\n     * GStreamer version.\n     * <p>\n     * <b>The library only supports major version 1</b>\n     *\n     * @param major Major version of GStreamer\n     * @param minor Minor version of GStreamer\n     * @param micro Micro (patch) version of GStreamer\n     * @param nano Nano The nano version of GStreamer : Actual releases have 0,\n     * GIT versions have 1, prerelease versions have 2\n     */\n    public Version(int major, int minor, int micro, int nano) {\n        this.major = major;\n        this.minor = minor;\n        this.micro = micro;\n        this.nano = nano;\n    }\n\n    /**\n     * Gets a string representation of the version.\n     *\n     * @return a string representing the version.\n     */\n    @Override\n    public String toString() {\n        return String.format(\"%d.%d.%d%s\",\n                major, minor, micro,\n                nano == 1 ? \" (CVS)\" : nano >= 2 ? \" (Pre-release)\" : \"\");\n    }\n\n    /**\n     * Gets the major version of GStreamer.\n     *\n     * @return the major version.\n     */\n    public int getMajor() {\n        return major;\n    }\n\n    /**\n     * Gets the minor version of GStreamer.\n     *\n     * @return the minor version.\n     */\n    public int getMinor() {\n        return minor;\n    }\n\n    /**\n     * Gets the micro version of GStreamer.\n     *\n     * @return the micro version.\n     */\n    public int getMicro() {\n        return micro;\n    }\n\n    /**\n     * Gets the nano version of GStreamer. Actual releases have 0, GIT versions\n     * have 1, prerelease versions have 2\n     *\n     * @return the nano version.\n     */\n    public int getNano() {\n        return nano;\n    }\n\n    /**\n     * Check whether this version is equal to or greater than the passed in\n     * version. Roughly comparable to GST_CHECK_VERSION\n     *\n     * @param required version to check against\n     * @return true if this version satisfies the required version\n     */\n    public boolean checkSatisfies(Version required) {\n        return (major == required.major && minor > required.minor)\n                || (major == required.major && minor == required.minor && micro >= required.micro);\n    }\n\n    /**\n     * Create a Version with specified major and minor version, and micro and\n     * nano version set to zero. Useful for specifying a required version in\n     * {@link Gst#init(org.freedesktop.gstreamer.Version)}.\n     * <p>\n     * <b>The library only supports major version 1</b>\n     * <p>\n     * Unlike the constructor this method will throw an exception if the version\n     * is not greater or equal to {@link #BASELINE}, or the major version isn't\n     * 1.\n     *\n     * @param major major version, currently must be 1\n     * @param minor minor version, greater or equal to 8\n     * @return requested version\n     * @throws IllegalArgumentException if the requested version is invalid\n     */\n    public static Version of(int major, int minor) {\n        if (major == BASELINE.getMajor()\n                && minor >= BASELINE.getMinor()) {\n            return new Version(major, minor);\n        }\n        throw new IllegalArgumentException(\"Invalid version\");\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/controller/ARGBControlBinding.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.controller;\n\nimport org.freedesktop.gstreamer.ControlBinding;\nimport org.freedesktop.gstreamer.ControlSource;\nimport org.freedesktop.gstreamer.GstObject;\nimport org.freedesktop.gstreamer.glib.GObject;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GstARGBControlBindingPtr;\nimport org.freedesktop.gstreamer.lowlevel.GstControlSourcePtr;\nimport org.freedesktop.gstreamer.lowlevel.GstDirectControlBindingPtr;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstControllerAPI.GSTCONTROLLER_API;\nimport org.freedesktop.gstreamer.lowlevel.GstObjectPtr;\n\n/**\n * Attachment for control sources to ARGB properties\n * <p>\n * A value mapping object that attaches multiple control sources to int GObject\n * properties representing colors. A control value of 0.0 will turn the color\n * component off and a value of 1.0 will be the color level.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstARGBControlBinding.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstARGBControlBinding.html</a>\n * <p>\n */\npublic class ARGBControlBinding extends ControlBinding {\n\n    public static final String GTYPE_NAME = \"GstARGBControlBinding\";\n\n    ARGBControlBinding(Initializer init) {\n        this(new Handle(\n                init.ptr.as(GstARGBControlBindingPtr.class, GstARGBControlBindingPtr::new),\n                init.ownsHandle),\n                init.needRef);\n    }\n\n    private ARGBControlBinding(Handle handle, boolean needRef) {\n        super(handle, needRef);\n    }\n\n    /**\n     * Create a new control-binding that attaches the given\n     * {@link ControlSource} to the {@link GObject} property.\n     *\n     * @param object the object of the property\n     * @param propertyName the property-name to attach the control source\n     * @param controlSourceA the control source for the alpha channel\n     * @param controlSourceR the control source for the red channel\n     * @param controlSourceG the control source for the green channel\n     * @param controlSourceB the control source for the blue channel\n     * @return new ARGBControlBinding\n     */\n    public static ARGBControlBinding create(GstObject object,\n            String propertyName,\n            ControlSource controlSourceA,\n            ControlSource controlSourceR,\n            ControlSource controlSourceG,\n            ControlSource controlSourceB) {\n        GstARGBControlBindingPtr ptr = GSTCONTROLLER_API.gst_argb_control_binding_new(\n                Natives.getPointer(object).as(GstObjectPtr.class, GstObjectPtr::new),\n                propertyName,\n                controlSourcePtr(controlSourceA),\n                controlSourcePtr(controlSourceR),\n                controlSourcePtr(controlSourceG),\n                controlSourcePtr(controlSourceB));\n        return new ARGBControlBinding(new Handle(ptr, true), false);\n    }\n\n    private static GstControlSourcePtr controlSourcePtr(ControlSource cs) {\n        return cs == null ? null\n                : Natives.getPointer(cs).as(GstControlSourcePtr.class, GstControlSourcePtr::new);\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/controller/Controllers.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.controller;\n\nimport java.util.stream.Stream;\nimport org.freedesktop.gstreamer.glib.NativeObject;\nimport static org.freedesktop.gstreamer.glib.Natives.registration;\n\n/**\n *  Controllers registration\n */\npublic class Controllers implements NativeObject.TypeProvider {\n\n    @Override\n    public Stream<NativeObject.TypeRegistration<?>> types() {\n        return Stream.of(\n                registration(ARGBControlBinding.class,\n                        ARGBControlBinding.GTYPE_NAME,\n                        ARGBControlBinding::new),\n                registration(DirectControlBinding.class,\n                        DirectControlBinding.GTYPE_NAME,\n                        DirectControlBinding::new),\n                registration(ProxyControlBinding.class,\n                        ProxyControlBinding.GTYPE_NAME,\n                        ProxyControlBinding::new),\n                registration(InterpolationControlSource.class,\n                        InterpolationControlSource.GTYPE_NAME,\n                        InterpolationControlSource::new),\n                registration(TriggerControlSource.class,\n                        TriggerControlSource.GTYPE_NAME,\n                        TriggerControlSource::new),\n                registration(LFOControlSource.class,\n                        LFOControlSource.GTYPE_NAME,\n                        LFOControlSource::new),\n                registration(TimedValueControlSource.class,\n                        TimedValueControlSource.GTYPE_NAME,\n                        TimedValueControlSource::new)\n        );\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/controller/DirectControlBinding.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.controller;\n\nimport org.freedesktop.gstreamer.ControlBinding;\nimport org.freedesktop.gstreamer.ControlSource;\nimport org.freedesktop.gstreamer.GstObject;\nimport org.freedesktop.gstreamer.glib.GObject;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GstControlSourcePtr;\nimport org.freedesktop.gstreamer.lowlevel.GstDirectControlBindingPtr;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstControllerAPI.GSTCONTROLLER_API;\nimport org.freedesktop.gstreamer.lowlevel.GstObjectPtr;\n\n/**\n * Direct attachment for control sources.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstDirectControlBinding.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstDirectControlBinding.html</a>\n * <p>\n */\npublic class DirectControlBinding extends ControlBinding {\n    \n    public static final String GTYPE_NAME = \"GstDirectControlBinding\";\n\n    DirectControlBinding(Initializer init) {\n        this(new Handle(\n                init.ptr.as(GstDirectControlBindingPtr.class, GstDirectControlBindingPtr::new),\n                init.ownsHandle),\n                init.needRef);\n    }\n\n    private DirectControlBinding(Handle handle, boolean needRef) {\n        super(handle, needRef);\n    }\n\n    /**\n     * Create a new control-binding that attaches the {@link ControlSource } to\n     * the {@link GObject} property. It will map the control source range [0.0\n     * ... 1.0] to the full target property range, and clip all values outside\n     * this range.\n     *\n     * @param object the object of the property\n     * @param propertyName the property-name to attach the control source\n     * @param controlSource the control source\n     * @return new DirectControlBinding\n     */\n    public static DirectControlBinding create(GstObject object, String propertyName, ControlSource controlSource) {\n        GstDirectControlBindingPtr ptr = GSTCONTROLLER_API.gst_direct_control_binding_new(\n                Natives.getPointer(object).as(GstObjectPtr.class, GstObjectPtr::new),\n                propertyName,\n                Natives.getPointer(controlSource).as(GstControlSourcePtr.class, GstControlSourcePtr::new));\n        return new DirectControlBinding(new Handle(ptr, true), false);\n    }\n    \n    /**\n     * Create a new control-binding that attaches the {@link ControlSource } to\n     * the {@link GObject} property. It will directly map the control source\n     * values to the target property range without any transformations.\n     *\n     * @param object the object of the property\n     * @param propertyName the property-name to attach the control source\n     * @param controlSource the control source\n     * @return new DirectControlBinding\n     */\n    public static DirectControlBinding createAbsolute(GstObject object,\n            String propertyName, ControlSource controlSource) {\n        GstDirectControlBindingPtr ptr = GSTCONTROLLER_API.gst_direct_control_binding_new_absolute(\n                Natives.getPointer(object).as(GstObjectPtr.class, GstObjectPtr::new),\n                propertyName,\n                Natives.getPointer(controlSource).as(GstControlSourcePtr.class, GstControlSourcePtr::new));\n        return new DirectControlBinding(new Handle(ptr, true), false);\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/controller/InterpolationControlSource.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.controller;\n\nimport org.freedesktop.gstreamer.ControlSource;\nimport org.freedesktop.gstreamer.glib.NativeEnum;\nimport org.freedesktop.gstreamer.lowlevel.GstInterpolationControlSourcePtr;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstControllerAPI.GSTCONTROLLER_API;\n\n/**\n * Interpolation control source.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstInterpolationControlSource.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstInterpolationControlSource.html</a>\n * <p>\n * InterpolationControlSource is a {@link ControlSource}, that interpolates\n * values between user-given control points. It supports several interpolation\n * modes and property types.\n * <p>\n * To use InterpolationControlSource create a new instance, bind it to a\n * GParamSpec and set some control points by calling {@link TimedValueControlSource#set(long, double)\n * }.\n * <p>\n * All functions are MT-safe.\n */\npublic class InterpolationControlSource extends TimedValueControlSource {\n    \n    public static final String GTYPE_NAME = \"GstInterpolationControlSource\";\n\n    /**\n     * Create a new, unbound InterpolationControlSource.\n     */\n    public InterpolationControlSource() {\n        this(new Handle(GSTCONTROLLER_API.gst_interpolation_control_source_new(), true), false);\n    }\n    \n    InterpolationControlSource(Initializer init) {\n        this(new Handle(\n                init.ptr.as(GstInterpolationControlSourcePtr.class,\n                        GstInterpolationControlSourcePtr::new),\n                init.ownsHandle),\n                init.needRef);\n    }\n\n    private InterpolationControlSource(Handle handle, boolean needRef) {\n        super(handle, needRef);\n    }\n\n    /**\n     * Interpolation mode to use.\n     * \n     * @param mode\n     * @return this\n     */\n    public InterpolationControlSource setMode(InterpolationMode mode) {\n        set(\"mode\", mode.intValue());\n        return this;\n    }\n    \n    /**\n     * Current interpolation mode.\n     * \n     * @return mode\n     */\n    public InterpolationMode getMode() {\n        Object val = get(\"mode\");\n        if (val instanceof Integer) {\n            int nativeInt = (Integer) val;\n            return NativeEnum.fromInt(InterpolationMode.class, nativeInt);\n        }\n        return InterpolationMode.NONE;\n    }\n    \n    \n    private static class Handle extends TimedValueControlSource.Handle {\n\n        public Handle(GstInterpolationControlSourcePtr ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/controller/InterpolationMode.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.controller;\n\nimport org.freedesktop.gstreamer.glib.NativeEnum;\n\n/**\n * The various interpolation modes available for use with\n * {@link InterpolationControlSource}.\n */\n// https://gitlab.freedesktop.org/gstreamer/gstreamer/blob/master/libs/gst/controller/gstinterpolationcontrolsource.h#L64\npublic enum InterpolationMode implements NativeEnum<InterpolationMode> {\n\n    /**\n     * Steps-like interpolation, default.\n     */\n    NONE(0),\n    /**\n     * Linear interpolation.\n     */\n    LINEAR(1),\n    /**\n     * Cubic interpolation (natural), may overshoot the min or max values set by\n     * the control point, but is more 'curvy'.\n     */\n    CUBIC(2),\n    /**\n     * Monotonic cubic interpolation, will not produce any values outside of the\n     * min-max range set by the control points.\n     */\n    CUBIC_MONOTONIC(3);\n\n    private final int value;\n\n    private InterpolationMode(int value) {\n        this.value = value;\n    }\n\n    @Override\n    public int intValue() {\n        return value;\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/controller/LFOControlSource.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.controller;\n\nimport org.freedesktop.gstreamer.ControlSource;\nimport org.freedesktop.gstreamer.glib.NativeEnum;\nimport static org.freedesktop.gstreamer.lowlevel.GstControllerAPI.GSTCONTROLLER_API;\nimport org.freedesktop.gstreamer.lowlevel.GstLFOControlSourcePtr;\n\n/**\n * LFO control source.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstLFOControlSource.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstLFOControlSource.html</a>\n * <p>\n * LFOControlSource is a {@link ControlSource}, that provides several periodic\n * waveforms as control values.\n * <p>\n * To use InterpolationControlSource create a new instance, bind it to a\n * GParamSpec and set the relevant properties.\n * <p>\n * All functions are MT-safe.\n */\npublic class LFOControlSource extends ControlSource {\n\n    public static final String GTYPE_NAME = \"GstLFOControlSource\";\n    \n    /**\n     * Create a new, unbound LFOControlSource.\n     */\n    public LFOControlSource() {\n        this(new Handle(GSTCONTROLLER_API.gst_lfo_control_source_new(), true), false);\n    }\n\n    LFOControlSource(Initializer init) {\n        this(new Handle(\n                init.ptr.as(GstLFOControlSourcePtr.class,\n                        GstLFOControlSourcePtr::new),\n                init.ownsHandle),\n                init.needRef);\n    }\n\n    private LFOControlSource(Handle handle, boolean needRef) {\n        super(handle, needRef);\n    }\n\n    /**\n     * Specifies the amplitude for the waveform of this LFOControlSource.\n     * <p>\n     * Allowed values: [0,1]\n     * <p>\n     * Default value: 1\n     *\n     * @param value amplitude between 0 and 1\n     * @return this\n     */\n    public LFOControlSource setAmplitude(double value) {\n        set(\"amplitude\", value);\n        return this;\n    }\n\n    /**\n     * Get the amplitude of the waveform.\n     *\n     * @return amplitude\n     */\n    public double getAmplitude() {\n        Object val = get(\"amplitude\");\n        if (val instanceof Double) {\n            return (double) val;\n        }\n        return 1;\n    }\n\n    /**\n     * Specifies the frequency that should be used for the waveform of this\n     * LFOControlSource. It should be large enough so that the period is longer\n     * than one nanosecond.\n     * <p>\n     * Allowed values: >= {@link Double#MIN_VALUE }\n     * <p>\n     * Default value: 1\n     *\n     * @param value frequency >= {@link Double#MIN_VALUE }\n     * @return this\n     */\n    public LFOControlSource setFrequency(double value) {\n        set(\"frequency\", value);\n        return this;\n    }\n\n    /**\n     * Get the frequency of the waveform.\n     *\n     * @return amplitude\n     */\n    public double getFrequency() {\n        Object val = get(\"frequency\");\n        if (val instanceof Double) {\n            return (double) val;\n        }\n        return 1;\n    }\n\n    /**\n     * Specifies the value offset for the waveform of this LFOControlSource.\n     * <p>\n     * Allowed values: [0,1]\n     * <p>\n     * Default value: 1\n     *\n     * @param value offset between 0 and 1\n     * @return this\n     */\n    public LFOControlSource setOffset(double value) {\n        set(\"offset\", value);\n        return this;\n    }\n\n    /**\n     * Get the value offset of the waveform.\n     *\n     * @return offset\n     */\n    public double getOffset() {\n        Object val = get(\"offset\");\n        if (val instanceof Double) {\n            return (double) val;\n        }\n        return 1;\n    }\n\n    /**\n     * Specifies the timeshift to the right that should be used for the waveform\n     * of this LFOControlSource in nanoseconds.\n     * <p>\n     * Default value: 0\n     *\n     * @param value timeshift in nanoseconds\n     * @return this\n     */\n    public LFOControlSource setTimeshift(long value) {\n        set(\"timeshift\", value);\n        return this;\n    }\n\n    /**\n     * Get the timeshift of the waveform.\n     *\n     * @return timeshift\n     */\n    public long getTimeshift() {\n        Object val = get(\"timeshift\");\n        if (val instanceof Long) {\n            return (long) val;\n        }\n        return 1;\n    }\n\n    /**\n     * Specifies the waveform that should be used for this LFOControlSource.\n     * <p>\n     * Default value: {@link LFOWaveform#SINE }\n     *\n     * @param value waveform\n     * @return this\n     */\n    public LFOControlSource setWaveform(LFOWaveform value) {\n        set(\"waveform\", value.intValue());\n        return this;\n    }\n\n    /**\n     * Get the waveform.\n     *\n     * @return waveform\n     */\n    public LFOWaveform getWaveform() {\n        Object val = get(\"waveform\");\n        if (val instanceof Integer) {\n            int nativeInt = (Integer) val;\n            return NativeEnum.fromInt(LFOWaveform.class, nativeInt);\n        }\n        return LFOWaveform.SINE;\n    }\n\n    private static class Handle extends ControlSource.Handle {\n\n        public Handle(GstLFOControlSourcePtr ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/controller/LFOWaveform.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.controller;\n\nimport org.freedesktop.gstreamer.glib.NativeEnum;\n\n/**\n * The various waveform modes available for use with {@link LFOControlSource}\n */\n// https://gitlab.freedesktop.org/gstreamer/gstreamer/blob/master/libs/gst/controller/gstlfocontrolsource.h#L60\npublic enum LFOWaveform implements NativeEnum<LFOWaveform> {\n\n    /**\n     * Sine waveform.\n     */\n    SINE(0),\n    \n    /**\n     * Square waveform.\n     */\n    SQUARE(1),\n\n    /**\n     * Saw waveform.\n     */\n    SAW(2),\n\n    /**\n     * Reverse saw waveform.\n     */\n    REVERSE_SAW(3),\n\n    /**\n     * Triangle waveform.\n     */\n    TRIANGLE(4)\n    ;\n\n        \n    private final int value;\n    \n    private LFOWaveform(int value) {\n        this.value = value;\n    }\n        \n    @Override\n    public int intValue() {\n        return value;\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/controller/ProxyControlBinding.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.controller;\n\nimport org.freedesktop.gstreamer.ControlBinding;\nimport org.freedesktop.gstreamer.Gst;\nimport org.freedesktop.gstreamer.GstObject;\nimport org.freedesktop.gstreamer.glib.Natives;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstControllerAPI.GSTCONTROLLER_API;\nimport org.freedesktop.gstreamer.lowlevel.GstObjectPtr;\nimport org.freedesktop.gstreamer.lowlevel.GstProxyControlBindingPtr;\n\n/**\n * Attachment for forwarding control sources\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/gstreamer-libs-GstProxyControlBinding.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/gstreamer-libs-GstProxyControlBinding.html</a>\n * <p>\n */\n@Gst.Since(minor = 12)\npublic class ProxyControlBinding extends ControlBinding {\n    \n    public static final String GTYPE_NAME = \"GstProxyControlBinding\";\n\n    ProxyControlBinding(Initializer init) {\n        this(new Handle(\n                init.ptr.as(GstProxyControlBindingPtr.class, GstProxyControlBindingPtr::new),\n                init.ownsHandle),\n                init.needRef);\n    }\n\n    private ProxyControlBinding(Handle handle, boolean needRef) {\n        super(handle, needRef);\n    }\n\n    /**\n     * Create a ProxyControlBinding that forwards all access to data or\n     * syncValues() requests from propertyName on object to the control\n     * binding at refPropertyName on refObject .\n     *\n     * @param object the object of the property\n     * @param propertyName the property-name to attach the control source\n     * @param refObject a GstObject to forward all ControlBinding requests to\n     * @param refPropertyName the property name in refObject to control\n     * @return new ProxyControlBinding\n     */\n    @Gst.Since(minor = 12)\n    public static ProxyControlBinding create(GstObject object, String propertyName,\n            GstObject refObject, String refPropertyName) {\n        GstProxyControlBindingPtr ptr = GSTCONTROLLER_API.gst_proxy_control_binding_new(\n                Natives.getPointer(object).as(GstObjectPtr.class, GstObjectPtr::new),\n                propertyName,\n                Natives.getPointer(refObject).as(GstObjectPtr.class, GstObjectPtr::new),\n                refPropertyName);\n        return new ProxyControlBinding(new Handle(ptr, true), false);\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/controller/TimedValueControlSource.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.controller;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport org.freedesktop.gstreamer.ControlSource;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI.GList;\nimport static org.freedesktop.gstreamer.lowlevel.GstControllerAPI.GSTCONTROLLER_API;\nimport org.freedesktop.gstreamer.lowlevel.GstTimedValueControlSourcePtr;\n\n/**\n * Timed value control source base class.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstTimedValueControlSource.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstTimedValueControlSource.html</a>\n * <p>\n * Base class for {@link ControlSource} that use time-stamped values.\n * <p>\n * When overriding bind, chain up first to give this bind implementation a\n * chance to setup things.\n * <p>\n * All functions are MT-safe.\n */\npublic class TimedValueControlSource extends ControlSource {\n    \n    public static final String GTYPE_NAME = \"GstTimedValueControlSource\";\n    \n    private final Handle handle;\n\n    protected TimedValueControlSource(Handle handle, boolean needRef) {\n        super(handle, needRef);\n        this.handle = handle;\n    }\n\n    TimedValueControlSource(Initializer init) {\n        this(new Handle(\n                init.ptr.as(GstTimedValueControlSourcePtr.class,\n                        GstTimedValueControlSourcePtr::new),\n                init.ownsHandle),\n                init.needRef);\n    }\n\n    /**\n     * Set the value of given controller-handled property at a certain time.\n     *\n     * @param timestamp the time the control-change is scheduled for\n     * @param value the control value\n     * @return false if the value could not be set\n     */\n    public boolean set(long timestamp, double value) {\n        return GSTCONTROLLER_API.gst_timed_value_control_source_set(\n                handle.getPointer(), timestamp, value);\n    }\n    \n    /**\n     * Sets multiple timed values at once.\n     *\n     * @param timedValues a list of {@link TimedValue}\n     * @return false if the values could not be set\n     */\n    public boolean setFromList(List<TimedValue> timedValues) {\n        for (TimedValue timedvalue : timedValues) {\n            boolean ok = set(timedvalue.timestamp, timedvalue.value);\n            if (!ok) {\n                return false;\n            }\n        }\n        return true;\n    }\n    \n    /**\n     * Returns a copy of the list of {@link TimedValue} for the given property.\n     * \n     * @return a list of TimedValue\n     */\n    public List<TimedValue> getAll() {\n        GList next = \n                GSTCONTROLLER_API.gst_timed_value_control_source_get_all(handle.getPointer());\n        List<TimedValue> list = new ArrayList<>();\n        while (next != null) {\n            if (next.data != null) {\n                list.add(new TimedValue(next.data.getLong(0), next.data.getDouble(Long.BYTES)));\n            }\n            next = next.next();\n        }\n        return list;\n    }\n    \n    /**\n     * Used to remove the value of given controller-handled property at a\n     * certain time.\n     * \n     * @param timestamp the time the control-change should be removed from\n     * @return FALSE if the value couldn't be unset (i.e. not found)\n     */\n    public boolean unset(long timestamp) {\n        return GSTCONTROLLER_API.gst_timed_value_control_source_unset(\n                handle.getPointer(), timestamp);\n    }\n    \n    /**\n     * Used to remove all time-stamped values of given controller-handled\n     * property.\n     */\n    public void unsetAll() {\n        GSTCONTROLLER_API.gst_timed_value_control_source_unset_all(handle.getPointer());\n    }\n    \n    /**\n     * Get the number of control points that are set.\n     * \n     * @return the number of control points that are set\n     */\n    public int getCount() {\n        return GSTCONTROLLER_API.gst_timed_value_control_source_get_count(handle.getPointer());\n    }\n    \n    /**\n     * Reset the controlled value cache.\n     */\n    public void invalidateCache() {\n        GSTCONTROLLER_API.gst_timed_value_control_invalidate_cache(handle.getPointer());\n    }\n    \n\n    protected static class Handle extends ControlSource.Handle {\n\n        public Handle(GstTimedValueControlSourcePtr ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n\n        @Override\n        protected GstTimedValueControlSourcePtr getPointer() {\n            return (GstTimedValueControlSourcePtr) super.getPointer();\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/controller/TriggerControlSource.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.controller;\n\nimport org.freedesktop.gstreamer.ControlSource;\nimport org.freedesktop.gstreamer.glib.NativeEnum;\nimport org.freedesktop.gstreamer.lowlevel.GstInterpolationControlSourcePtr;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstControllerAPI.GSTCONTROLLER_API;\nimport org.freedesktop.gstreamer.lowlevel.GstTriggerControlSourcePtr;\n\n/**\n * Trigger control source.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstTriggerControlSource.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstTriggerControlSource.html</a>\n * <p>\n * TriggerControlSource is a {@link ControlSource}, that returns values from\n * user-given control points. It allows for a tolerance on time-stamps.\n * <p>\n * To use TriggerControlSource create a new instance, bind it to a GParamSpec\n * and set some control points by calling\n * {@link TimedValueControlSource#set(long, double)}.\n * <p>\n * All functions are MT-safe.\n */\npublic class TriggerControlSource extends TimedValueControlSource {\n\n    public static final String GTYPE_NAME = \"GstTriggerControlSource\";\n\n    /**\n     * Create a new, unbound InterpolationControlSource.\n     */\n    public TriggerControlSource() {\n        this(new Handle(GSTCONTROLLER_API.gst_trigger_control_source_new(), true), false);\n    }\n\n    TriggerControlSource(Initializer init) {\n        this(new Handle(\n                init.ptr.as(GstTriggerControlSourcePtr.class,\n                        GstTriggerControlSourcePtr::new),\n                init.ownsHandle),\n                init.needRef);\n    }\n\n    private TriggerControlSource(Handle handle, boolean needRef) {\n        super(handle, needRef);\n    }\n\n    /**\n     * Amount of nanoseconds a control time can be off to still trigger.\n     * <p>\n     * Allowed values: >= 0\n     * <p>\n     * Default value: 0\n     *\n     * @param tolerance in nanoseconds\n     * @return this\n     */\n    public TriggerControlSource setTolerance(long tolerance) {\n        set(\"tolerance\", tolerance);\n        return this;\n    }\n\n    /**\n     * Current tolerance in nanoseconds.\n     *\n     * @return tolerance in nanoseconds\n     */\n    public long getTolerance() {\n        Object val = get(\"tolerance\");\n        if (val instanceof Long) {\n            return (long) val;\n        }\n        return 0L;\n    }\n\n    private static class Handle extends TimedValueControlSource.Handle {\n\n        public Handle(GstTriggerControlSourcePtr ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/device/Device.java",
    "content": "/*\n * \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2015 Andres Colubri <andres.colubri@gmail.com>\n * Copyright (C) 2013 Olivier Crete <olivier.crete@collabora.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.device;\n\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.Element;\nimport org.freedesktop.gstreamer.GstObject;\nimport org.freedesktop.gstreamer.Structure;\n\nimport static org.freedesktop.gstreamer.lowlevel.GlibAPI.GLIB_API;\nimport static org.freedesktop.gstreamer.lowlevel.GstDeviceAPI.GSTDEVICE_API;\n\n/**\n * Devices are objects representing a device, they contain relevant metadata\n * about the device, such as its class and the GstCaps representing the media\n * types it can produce or handle.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/gstreamer-GstDevice.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/gstreamer-GstDevice.html</a>\n * <p>\n * Device objects are created by {@link DeviceProvider} objects, which can be\n * aggregated by {@link DeviceMonitor} objects.\n */\npublic class Device extends GstObject {\n\n    public static final String GTYPE_NAME = \"GstDevice\";\n\n    Device(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Creates the element with all of the required parameters set to use this\n     * device.\n     *\n     * @param name name of new element, or NULL to automatically create a unique\n     * name\n     * @return a new {@link Element} configured to use this device.\n     */\n    public Element createElement(String name) {\n        return GSTDEVICE_API.gst_device_create_element(this, name);\n    }\n\n    /**\n     * Get the {@link Caps} that this device supports.\n     *\n     * @return The Caps supported by this device.\n     */\n    public Caps getCaps() {\n        return GSTDEVICE_API.gst_device_get_caps(this);\n    }\n\n    /**\n     * Gets the \"class\" of a device. This is a \"/\" separated list of classes\n     * that represent this device. They are a subset of the classes of the\n     * {@link DeviceProvider} that produced this device.\n     *\n     * @return class the device class\n     */\n    public String getDeviceClass() {\n        Pointer ptr = GSTDEVICE_API.gst_device_get_device_class(this);\n        String ret = ptr.getString(0);\n        GLIB_API.g_free(ptr);\n        return ret;\n    }\n\n    /**\n     * Gets the user-friendly name of the device.\n     *\n     * @return name of the device\n     */\n    public String getDisplayName() {\n        Pointer ptr = GSTDEVICE_API.gst_device_get_display_name(this);\n        String ret = ptr.getString(0);\n        GLIB_API.g_free(ptr);\n        return ret;\n    }\n\n    /**\n     * Check if device matches all of the given classes.\n     *\n     * @param classes a \"/\"-separated list of device classes to match, only\n     * match if all classes are matched\n     * @return true if device matches\n     */\n    public boolean hasClasses(String classes) {\n        return GSTDEVICE_API.gst_device_has_classes(this, classes);\n    }\n\n    /**\n     * Check if device matches all of the given classes.\n     *\n     * @param classes an array of classes to match, only match if all classes\n     * are matched.\n     * @return true if device matches\n     */\n    public boolean hasClasses(String[] classes) {\n        return GSTDEVICE_API.gst_device_has_classesv(this, classes);\n    }\n\n    /**\n     * Tries to reconfigure an existing element to use the device. If this\n     * function fails, then one must destroy the element and create a new one\n     * using {@link #createElement(java.lang.String) }\n     * <p>\n     * Note: This should only be implemented for elements can change their\n     * device in the PLAYING state.\n     * \n     * @param element the element to be configured\n     * @return true if the element could be reconfigured to use this device\n     */\n    public boolean reconfigureElement(Element element) {\n        return GSTDEVICE_API.gst_device_reconfigure_element(this, element);\n    }\n\n    /**\n     * Gets the extra properties of a device.\n     * \n     * @return The extra properties or NULL when there are none.\n     */\n    public Structure getProperties() {\n        return GSTDEVICE_API.gst_device_get_properties(this);\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/device/DeviceMonitor.java",
    "content": "/*\n * \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2015 Andres Colubri <andres.colubri@gmail.com>\n * Copyright (C) 2013 Olivier Crete <olivier.crete@collabora.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.device;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport org.freedesktop.gstreamer.Bus;\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.GstObject;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI.GList;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstDeviceMonitorAPI.GSTDEVICEMONITOR_API;\n\n/**\n * A device monitor and prober\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/gstreamer-GstDeviceMonitor.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/gstreamer-GstDeviceMonitor.html</a>\n * <p>\n * Applications should create a DeviceMonitor when they want to probe, list and\n * monitor devices of a specific type. The DeviceMonitor will create the\n * appropriate {@link DeviceProvider} objects and manage them. It will then post\n * messages on its {@link Bus} for devices that have been added and removed.\n * <p>\n * The device monitor will monitor all devices matching the filters that the\n * application has set.\n */\npublic class DeviceMonitor extends GstObject {\n\n    public static final String GTYPE_NAME = \"GstDeviceMonitor\";\n\n    public DeviceMonitor() {\n        super(Natives.initializer(GSTDEVICEMONITOR_API.ptr_gst_device_monitor_new(), false, true));\n    }\n\n    DeviceMonitor(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Get the {@link Bus} for this DeviceMonitor\n     *\n     * @return bus\n     */\n    public Bus getBus() {\n        return GSTDEVICEMONITOR_API.gst_device_monitor_get_bus(this);\n    }\n\n    /**\n     * Adds a filter for which devices will be monitored, any device that\n     * matches all these classes and the {@link Caps} will be returned.\n     * <p>\n     * If this function is called multiple times to add more filters, each will\n     * be matched independently. That is, adding more filters will not further\n     * restrict what devices are matched.\n     * <p>\n     * The GstCaps supported by the device as returned by gst_device_get_caps()\n     * are not intersected with caps filters added using this function.\n     * <p>\n     * Filters must be added before the GstDeviceMonitor is started.\n     *\n     * @param classes device classes to use as filter or NULL for any class.\n     * @param caps the GstCaps to filter or NULL for ANY.\n     * @return id the id of the new filter or 0 if no provider matched the\n     * filter's classes.\n     */\n    public int addFilter(String classes, Caps caps) {\n        return GSTDEVICEMONITOR_API.gst_device_monitor_add_filter(this, classes, caps);\n    }\n\n    /**\n     * Remove a filter from the DeviceMonitor using the id that was returned\n     * from {@link #addFilter(java.lang.String, org.freedesktop.gstreamer.Caps)\n     * }\n     *\n     * @param filterId of filter to remove\n     * @return true if the filter id was valid and the filter was removed\n     */\n    public boolean removeFilter(int filterId) {\n        return GSTDEVICEMONITOR_API.gst_device_monitor_remove_filter(this, filterId);\n    }\n\n    /**\n     * Starts monitoring the devices, once this has succeeded, the\n     * GST_MESSAGE_DEVICE_ADDED and GST_MESSAGE_DEVICE_REMOVED messages will be\n     * emitted on the bus when the list of devices changes.\n     *\n     * @return true if the device monitoring could be started\n     */\n    public boolean start() {\n        return GSTDEVICEMONITOR_API.gst_device_monitor_start(this);\n    }\n\n    /**\n     * Stop monitoring devices.\n     */\n    public void stop() {\n        GSTDEVICEMONITOR_API.gst_device_monitor_stop(this);\n    }\n\n    /**\n     * Gets a list of devices from all of the relevant monitors. This may\n     * actually probe the hardware if the monitor is not currently started.\n     * \n     * @return list of {@link Device}\n     */\n    public List<Device> getDevices() {\n        GList glist = GSTDEVICEMONITOR_API.gst_device_monitor_get_devices(this);\n        List<Device> list = new ArrayList<>();\n\n        GList next = glist;\n        while (next != null) {\n            if (next.data != null) {\n                Device dev = new Device(Natives.initializer(next.data, false, true));\n                list.add(dev);\n            }\n            next = next.next();\n        }\n\n        return list;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/device/DeviceProvider.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2015 Andres Colubri <andres.colubri@gmail.com>\n * Copyright (C) 2013 Olivier Crete <olivier.crete@collabora.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.device;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport org.freedesktop.gstreamer.Bus;\nimport org.freedesktop.gstreamer.GstObject;\nimport org.freedesktop.gstreamer.Plugin;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GType;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI;\nimport org.freedesktop.gstreamer.lowlevel.GstDeviceProviderAPI;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstDeviceProviderAPI.GSTDEVICEPROVIDER_API;\n\n/**\n * A device provider.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/gstreamer-GstDeviceProvider.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/gstreamer-GstDeviceProvider.html</a>\n * <p>\n * A DeviceProvider subclass is provided by a plugin that handles devices if\n * there is a way to programatically list connected devices. It can also\n * optionally provide updates to the list of connected devices.\n * <p>\n * Each DeviceProvider subclass is a singleton, a plugin should normally provide\n * a single subclass for all devices.\n * <p>\n * Applications would normally use a {@link DeviceMonitor} to monitor devices\n * from all relevant providers.\n */\npublic class DeviceProvider extends GstObject {\n\n    public static final String GTYPE_NAME = \"GstDeviceProvider\";\n\n    DeviceProvider(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Whether the provider can monitor.\n     *\n     * @return true if the provider can monitor\n     */\n    public boolean canMonitor() {\n        return GSTDEVICEPROVIDER_API.gst_device_provider_can_monitor(this);\n    }\n\n//    /**\n//     * Set key with value as metadata in klass.\n//     *\n//     * @param klass class to set metadata for\n//     * @param key the key to set\n//     * @param value the value to set\n//     */\n//    public void addMetadata(GstDeviceProviderAPI.GstDeviceProviderClass klass, String key, String value) {\n//        GSTDEVICEPROVIDER_API.gst_device_provider_class_add_metadata(klass, key, value);\n//    }\n//\n//    /**\n//     * Get metadata with key in klass.\n//     *\n//     * @param klass class to get metadata for\n//     * @param key the key to get\n//     * @return the metadata for key\n//     */\n//    public String getMetadata(GstDeviceProviderAPI.GstDeviceProviderClass klass, String key) {\n//        return GSTDEVICEPROVIDER_API.gst_device_provider_class_get_metadata(klass, key);\n//    }\n\n//    public void setMetadata(GstDeviceProviderAPI.GstDeviceProviderClass klass,\n//            String longname, String classification, String description, String author) {\n//        GSTDEVICEPROVIDER_API.gst_device_provider_class_set_metadata(klass, longname, classification, description, author);\n//    }\n//    public void add(Device device) {\n//        GSTDEVICEPROVIDER_API.gst_device_provider_device_add(this, device);\n//    }\n//\n//    public void remove(Device device) {\n//        GSTDEVICEPROVIDER_API.gst_device_provider_device_remove(this, device);\n//    }\n    /**\n     * Get the {@link Bus} of this DeviceProvider\n     *\n     * @return bus\n     */\n    public Bus getBus() {\n        return GSTDEVICEPROVIDER_API.gst_device_provider_get_bus(this);\n    }\n\n    /**\n     * Gets a list of {@link Device} that this provider understands. This may\n     * actually probe the hardware if the provider is not currently started.\n     *\n     * @return device list\n     */\n    public List<Device> getDevices() {\n        GlibAPI.GList glist = GSTDEVICEPROVIDER_API.gst_device_provider_get_devices(this);\n        List<Device> list = new ArrayList<Device>();\n\n        GlibAPI.GList next = glist;\n        while (next != null) {\n            if (next.data != null) {\n                Device dev = new Device(Natives.initializer(next.data, true, true));\n                list.add(dev);\n            }\n            next = next.next();\n        }\n        \n\n        return list;\n    }\n\n    /**\n     * Retrieves the factory that was used to create this device provider.\n     *\n     * @return the {@link DeviceProviderFactory} used for creating this device\n     * provider.\n     */\n    public DeviceProviderFactory getFactory() {\n        return GSTDEVICEPROVIDER_API.gst_device_provider_get_factory(this);\n    }\n\n//    @TODO rethink this to not require GType\n//    /**\n//     * Create a new device providerfactory capable of instantiating objects of\n//     * the type and add the factory to plugin.\n//     * \n//     * @param plugin {@link Plugin} to register the device provider with, or NULL for a static device provider. \n//     * @param name name of device providers of this type\n//     * @param rank rank of device provider (higher rank means more importance when autoplugging)\n//     * @param type \n//     * @return\n//     */\n//    public boolean register(Plugin plugin, String name, int rank, GType type) {\n//        return GSTDEVICEPROVIDER_API.gst_device_provider_register(plugin, name, rank, type);\n//    }\n\n    /**\n     * Starts providering the devices. This will cause GST_MESSAGE_DEVICE_ADDED\n     * and GST_MESSAGE_DEVICE_REMOVED messages to be posted on the provider's\n     * bus when devices are added or removed from the system.\n     * <p>\n     * Since the DeviceProvider is a singleton, start may already have been\n     * called by another user of the object, {@link #stop() } needs to be called\n     * the same number of times.\n     *\n     * @return true if the device providering could be started.\n     */\n    public boolean start() {\n        return GSTDEVICEPROVIDER_API.gst_device_provider_start(this);\n    }\n\n    /**\n     * Decreases the use-count by one. If the use count reaches zero, this\n     * DeviceProvider will stop providering the devices. This needs to be called\n     * the same number of times that {@link #start() } was called.\n     */\n    public void stop() {\n        GSTDEVICEPROVIDER_API.gst_device_provider_stop(this);\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/device/DeviceProviderFactory.java",
    "content": "/*\n * Copyright (c) 2025 Neil C Smith\n * Copyright (c) 2015 Andres Colubri <andres.colubri@gmail.com>\n * Copyright (C) 2013 Olivier Crete <olivier.crete@collabora.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.device;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport org.freedesktop.gstreamer.GstObject;\nimport org.freedesktop.gstreamer.PluginFeature.Rank;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI.GList;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstDeviceProviderFactoryAPI.GSTDEVICEPROVIDERFACTORY_API;\nimport org.freedesktop.gstreamer.lowlevel.GstPluginAPI;\n\n/**\n * A factory for {@link DeviceProvider}\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstDeviceProviderFactory.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstDeviceProviderFactory.html</a>\n * <p>\n * DeviceProviderFactory is used to create instances of device providers. A\n * DeviceProviderfactory can be added to a Plugin as it is also a PluginFeature.\n *\n * Use the {@link #find(java.lang.String)} and\n * {@link #get()} functions to create device provider\n * instances or use {@link #getByName(java.lang.String)} as a convenient\n * shortcut.\n */\npublic class DeviceProviderFactory extends GstObject {\n\n    public static final String GTYPE_NAME = \"GstDeviceProviderFactory\";\n\n    DeviceProviderFactory(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Returns the {@link DeviceProvider} of the type defined by the given\n     * device provider factory.\n     *\n     * @return DeviceProvider or NULL if the device provider couldn't be\n     * created.\n     */\n    public DeviceProvider get() {\n        return GSTDEVICEPROVIDERFACTORY_API.gst_device_provider_factory_get(this);\n    }\n\n    \n    /**\n     * Get the metadata on factory with key.\n     *\n     * @param key\n     * @return the metadata with key on factory or null when there was no\n     * metadata with the given key .\n     */\n    public String getMetadata(String key) {\n        return GSTDEVICEPROVIDERFACTORY_API.gst_device_provider_factory_get_metadata(this, key);\n    }\n\n//    @TODO List<String> ??\n//    public String[] getMetadataKeys() {\n//        return GSTDEVICEPROVIDERFACTORY_API.gst_device_provider_factory_get_metadata_keys(this);\n//    }\n\n    /**\n     * Check if factory matches all of the given classes\n     *\n     * @param classes a \"/\" separate list of classes to match, only match if all\n     * classes are matched.\n     * @return true if factory matches\n     */\n    public boolean hasClasses(String classes) {\n        return GSTDEVICEPROVIDERFACTORY_API.gst_device_provider_factory_has_classes(this, classes);\n    }\n\n//    public boolean hasClasses(String[] classes) {\n//        return GSTDEVICEPROVIDERFACTORY_API.gst_device_provider_factory_has_classesv(this, classes);\n//    }\n    /**\n     * Search for an device provider factory of the given name.\n     *\n     * @param name name of factory to find\n     * @return DeviceProviderFactory if found, or null\n     */\n    public static DeviceProviderFactory find(String name) {\n        return GSTDEVICEPROVIDERFACTORY_API.gst_device_provider_factory_find(name);\n    }\n\n    /**\n     * Returns the device provider of the type defined by the given device\n     * provider factory.\n     *\n     * @param factoryName a named factory to instantiate\n     * @return DeviceProvider or NULL if the device provider couldn't be\n     * created.\n     */\n    public static DeviceProvider getByName(String factoryName) {\n        return GSTDEVICEPROVIDERFACTORY_API.gst_device_provider_factory_get_by_name(factoryName);\n    }\n    \n    /**\n     * Get a list of factories with a rank greater or equal to minrank . The\n     * list of factories is returned by decreasing rank.\n     * @param minRank minimum rank\n     * @return a list of\n     */\n    public static List<DeviceProviderFactory> getDeviceProviders(Rank minRank) {\n        GList glist = GSTDEVICEPROVIDERFACTORY_API.gst_device_provider_factory_list_get_device_providers(minRank);\n        List<DeviceProviderFactory> list = new ArrayList<>();\n        \n        GList next = glist;\n        while (next != null) {\n            if (next.data != null) {\n                DeviceProviderFactory factory =\n                        new DeviceProviderFactory(Natives.initializer(next.data, true, true));\n                list.add(factory);\n            }\n            next = next.next();\n        }\n        \n        GstPluginAPI.GSTPLUGIN_API.gst_plugin_list_free(glist);\n        \n        return list;\n    }\n//    public GType getDeviceProviderType() {\n//        return GSTDEVICEPROVIDERFACTORY_API.gst_device_provider_factory_get_device_provider_type(this);\n//    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/elements/AppSink.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2016 Christophe Lafolet\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2009 Wayne Meissner\n * Copyright (c) 2008 Wayne Meissner\n * Copyright (C) 2007 David Schleef <ds@schleef.org>\n *           (C) 2008 Wim Taymans <wim.taymans@gmail.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.elements;\n\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.Element;\nimport org.freedesktop.gstreamer.FlowReturn;\nimport org.freedesktop.gstreamer.Sample;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback;\nimport static org.freedesktop.gstreamer.lowlevel.AppAPI.APP_API;\n\n/**\n * A sink {@link Element} that provides an easy way for applications to extract\n * samples from a pipeline.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-libs/html/gst-plugins-base-libs-appsink.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-libs/html/gst-plugins-base-libs-appsink.html</a>\n * <p>\n * Appsink is a sink plugin that supports many different methods for making the\n * application get a handle on the GStreamer data in a pipeline. Unlike most\n * GStreamer elements, Appsink provides external API functions.\n * <p>\n * The normal way of retrieving samples from appsink is by using the\n * {@link #pullSample()} and {@link #pullPreroll()} methods. These methods block\n * until a sample becomes available in the sink or when the sink is shut down or\n * reaches EOS. (<em>TODO - not currently mapped in the Java bindings.</em>\n * There are also timed variants of these methods,\n * gst_app_sink_try_pull_sample() and gst_app_sink_try_pull_preroll(), which\n * accept a timeout parameter to limit the amount of time to wait).\n * <p>\n * Appsink will internally use a queue to collect buffers from the streaming\n * thread. If the application is not pulling samples fast enough, this queue\n * will consume a lot of memory over time. The \"max-buffers\" property can be\n * used to limit the queue size. The \"drop\" property controls whether the\n * streaming thread blocks or if older buffers are dropped when the maximum\n * queue size is reached. Note that blocking the streaming thread can negatively\n * affect real-time performance and should be avoided.\n * <p>\n * If a blocking behaviour is not desirable, setting the \"emit-signals\" property\n * to TRUE will make appsink emit the \"new-sample\" and \"new-preroll\" signals\n * when a sample can be pulled without blocking.\n * <p>\n * The \"caps\" property on appsink can be used to control the formats that\n * appsink can receive. This property can contain non-fixed caps, the format of\n * the pulled samples can be obtained by getting the sample caps.\n * <p>\n * If one of the pull-preroll or pull-sample methods return NULL, the appsink is\n * stopped or in the EOS state. You can check for the EOS state with the \"eos\"\n * property or with the {@link #isEOS()} method.\n * <p>\n * The eos signal can also be used to be informed when the EOS state is reached\n * to avoid polling.\n */\npublic class AppSink extends BaseSink {\n\n    public static final String GST_NAME = \"appsink\";\n    public static final String GTYPE_NAME = \"GstAppSink\";\n\n    AppSink(Initializer init) {\n        super(init);\n    }\n\n    public AppSink(String name) {\n        this(makeRawElement(GST_NAME, name));\n    }\n\n    /**\n     * Sets the {@link Caps} on the AppSink.\n     * <p>\n     * After calling this method, the sink will only accept Caps that match\n     * <tt>caps</tt>. If <tt>caps</tt> is non-fixed, you must check the caps on\n     * the buffers to get the actual used caps.\n     *\n     * @param caps the Caps to set.\n     */\n    @Override\n    public void setCaps(Caps caps) {\n        APP_API.gst_app_sink_set_caps(this, caps);\n    }\n\n    /**\n     * Gets the {@link Caps} configured on this AppSink\n     *\n     * @return the Caps accepted by this sink\n     */\n    public Caps getCaps() {\n        return APP_API.gst_app_sink_get_caps(this);\n    }\n\n    /**\n     * Check if this AppSink is EOS, which is when no more samples can be pulled\n     * because an EOS event was received.\n     * <p>\n     * This function also returns TRUE when the AppSink is not in the PAUSED or\n     * PLAYING state.\n     *\n     * @return true if no more buffers can be pulled and this AppSink is EOS.\n     */\n    public boolean isEOS() {\n        return APP_API.gst_app_sink_is_eos(this);\n    }\n\n    /**\n     * Get the last preroll {@link Sample}. This was the Sample that caused the\n     * AppSink to preroll in the PAUSED state.\n     * <p>\n     * This function is typically used when dealing with a pipeline in the\n     * PAUSED state. Calling this function after doing a seek will give the\n     * sample right after the seek position.\n     * <p>\n     * Calling this function will clear the internal reference to the preroll\n     * buffer.\n     * <p>\n     * Note that the preroll sample will also be returned as the first sample\n     * when calling {@link #pullSample() }\n     * <p>\n     * If an EOS event was received before any buffers, this function returns\n     * NULL. Use {@link #isEOS() } to check for the EOS condition.\n     * <p>\n     * This function blocks until a preroll sample or EOS is received or the\n     * AppSink element is set to the READY/NULL state.\n     *\n     * @return a Sample, or null if the AppSink is stopped or EOS\n     */\n    public Sample pullPreroll() {\n        return APP_API.gst_app_sink_pull_preroll(this);\n    }\n\n    /**\n     * This function blocks until a {@link Sample} or EOS becomes available or\n     * the AppSink element is set to the READY/NULL state.\n     * <p>\n     * This function will only return samples when the AppSink is in the PLAYING\n     * state. All rendered buffers will be put in a queue so that the\n     * application can pull samples at its own rate. Note that when the\n     * application does not pull samples fast enough, the queued buffers could\n     * consume a lot of memory, especially when dealing with raw video frames.\n     * <p>\n     * If an EOS event was received before any buffers, this function returns\n     * NULL. Use {@link #isEOS() } to check for the EOS condition.\n     *\n     * @return a Sample, or null if the AppSink is stopped or EOS\n     */\n    public Sample pullSample() {\n        return APP_API.gst_app_sink_pull_sample(this);\n    }\n\n    /**\n     * Signal emitted when this {@link AppSink} got EOS.\n     */\n    public static interface EOS {\n\n        /**\n         * EOS signal\n         *\n         * @param elem AppSink\n         */\n        public void eos(AppSink elem);\n    }\n\n    /**\n     * Adds a listener for the <code>eos</code> signal.\n     *\n     * @param listener\n     */\n    public void connect(final EOS listener) {\n        connect(EOS.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(AppSink elem) {\n                listener.eos(elem);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>eos</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(EOS listener) {\n        disconnect(EOS.class, listener);\n    }\n\n    /**\n     * Signal emitted when this {@link AppSink} when a new Sample is ready.\n     */\n    public static interface NEW_SAMPLE {\n\n        /**\n         * New Sample signal\n         *\n         * @param elem AppSink\n         * @return FlowReturn\n         */\n        public FlowReturn newSample(AppSink elem);\n    }\n\n    /**\n     * Adds a listener for the <code>new-sample</code> signal. If a blocking\n     * behaviour is not desirable, setting the \"emit-signals\" property to TRUE\n     * will make appsink emit the \"new-sample\" and \"new-preroll\" signals when a\n     * buffer can be pulled without blocking.\n     *\n     * @param listener\n     */\n    public void connect(final NEW_SAMPLE listener) {\n        connect(NEW_SAMPLE.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public FlowReturn callback(AppSink elem) {\n                return listener.newSample(elem);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>new-sample</code> signal\n     *\n     * @param listener a listener that was previously added.\n     */\n    public void disconnect(NEW_SAMPLE listener) {\n        disconnect(NEW_SAMPLE.class, listener);\n    }\n\n    /**\n     * Signal emitted when this {@link AppSink} when a new buffer is ready.\n     */\n    public static interface NEW_PREROLL {\n\n        /**\n         * New preroll signal\n         *\n         * @param elem AppSink\n         * @return FlowReturn\n         */\n        public FlowReturn newPreroll(AppSink elem);\n    }\n\n    /**\n     * Adds a listener for the <code>new-preroll</code> signal. If a blocking\n     * behaviour is not desirable, setting the \"emit-signals\" property to TRUE\n     * will make appsink emit the \"new-buffer\" and \"new-preroll\" signals when a\n     * buffer can be pulled without blocking.\n     *\n     * @param listener\n     */\n    public void connect(final NEW_PREROLL listener) {\n        connect(NEW_PREROLL.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public FlowReturn callback(AppSink elem) {\n                return listener.newPreroll(elem);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>new-preroll</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(NEW_PREROLL listener) {\n        disconnect(NEW_PREROLL.class, listener);\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/elements/AppSrc.java",
    "content": "/*\n * Copyright (c) 2025 Neil C Smith\n * Copyright (c) 2009 Andres Colubri\n * Copyright (c) 2008 Wayne Meissner\n * Copyright (C) 2007 David Schleef <ds@schleef.org>\n *           (C) 2008 Wim Taymans <wim.taymans@gmail.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.elements;\n\nimport org.freedesktop.gstreamer.Buffer;\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.Element;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback;\nimport static org.freedesktop.gstreamer.lowlevel.AppAPI.APP_API;\n\nimport com.sun.jna.ptr.LongByReference;\nimport org.freedesktop.gstreamer.FlowReturn;\nimport org.freedesktop.gstreamer.Format;\nimport org.freedesktop.gstreamer.glib.NativeEnum;\n\n/**\n * A source {@link Element} that provides an easy way for applications to insert\n * data into a GStreamer pipeline.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-libs/html/gst-plugins-base-libs-appsrc.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-libs/html/gst-plugins-base-libs-appsrc.html</a>\n * <p>\n * Before operating appsrc, the {@link Caps} property must be set to fixed caps\n * describing the format of the data that will be pushed with appsrc. An\n * exception to this is when pushing buffers with unknown caps, in which case no\n * caps should be set. This is typically true of file-like sources that push raw\n * byte buffers. If you don't want to explicitly set the caps, you can use\n * gst_app_src_push_sample (<em>not yet mapped</em>). This method gets the caps\n * associated with the sample and sets them on the appsrc replacing any\n * previously set caps (if different from sample's caps).\n * <p>\n * The main way of handing data to the appsrc element is by calling the\n * {@link #pushBuffer(Buffer) } method or by emitting the push-buffer action\n * signal. This will put the buffer onto a queue from which appsrc will read\n * from in its streaming thread. It is important to note that data transport\n * will not happen from the thread that performed the push-buffer call.\n * <p>\n * The \"max-bytes\" property controls how much data can be queued in appsrc\n * before appsrc considers the queue full. A filled internal queue will always\n * signal the \"enough-data\" signal, which signals the application that it should\n * stop pushing data into appsrc. The \"block\" property will cause appsrc to\n * block the push-buffer method until free data becomes available again.\n * <p>\n * When the internal queue is running out of data, the \"need-data\" signal is\n * emitted, which signals the application that it should start pushing more data\n * into appsrc.\n * <p>\n * In addition to the \"need-data\" and \"enough-data\" signals, appsrc can emit the\n * \"seek-data\" signal when the \"stream-mode\" property is set to \"seekable\" or\n * \"random-access\". The signal argument will contain the new desired position in\n * the stream expressed in the unit set with the \"format\" property. After\n * receiving the seek-data signal, the application should push-buffers from the\n * new position.\n * <p>\n * These signals allow the application to operate the appsrc in two different\n * ways:\n * <p>\n * The push mode, in which the application repeatedly calls the\n * push-buffer/push-sample method with a new buffer/sample. Optionally, the\n * queue size in the appsrc can be controlled with the enough-data and need-data\n * signals by respectively stopping/starting the push-buffer/push-sample calls.\n * This is a typical mode of operation for the stream-type \"stream\" and\n * \"seekable\". Use this mode when implementing various network protocols or\n * hardware devices.\n * <p>\n * The pull mode, in which the need-data signal triggers the next push-buffer\n * call. This mode is typically used in the \"random-access\" stream-type. Use\n * this mode for file access or other randomly accessable sources. In this mode,\n * a buffer of exactly the amount of bytes given by the need-data signal should\n * be pushed into appsrc.\n * <p>\n * In all modes, the size property on appsrc should contain the total stream\n * size in bytes. Setting this property is mandatory in the random-access mode.\n * For the stream and seekable modes, setting this property is optional but\n * recommended.\n * <p>\n * When the application has finished pushing data into appsrc, it should call\n * {@link #endOfStream() } or emit the end-of-stream action signal. After this\n * call, no more buffers can be pushed into appsrc until a flushing seek occurs\n * or the state of the appsrc has gone through READY.\n */\npublic class AppSrc extends BaseSrc {\n\n    public static final String GST_NAME = \"appsrc\";\n    public static final String GTYPE_NAME = \"GstAppSrc\";\n\n    AppSrc(Initializer init) {\n        super(init);\n    }\n\n    public AppSrc(String name) {\n        this(makeRawElement(GST_NAME, name));\n    }\n\n    /**\n     * Set the capabilities on the appsrc element. This function takes a copy of\n     * the caps structure. After calling this method, the source will only\n     * produce caps that match caps . caps must be fixed and the caps on the\n     * buffers must match the caps or left NULL.\n     */\n    @Override\n    public void setCaps(Caps caps) {\n        APP_API.gst_app_src_set_caps(this, caps);\n    }\n\n    /**\n     * Get the configured Caps on the AppSrc.\n     *\n     * @return the caps\n     */\n    public Caps getCaps() {\n        return APP_API.gst_app_src_get_caps(this);\n    }\n\n    /**\n     * Set the size of the stream in bytes. A value of -1 means that the size is\n     * not known.\n     *\n     * @param size the size to set, or -1 if not known\n     */\n    public void setSize(long size) {\n        APP_API.gst_app_src_set_size(this, size);\n    }\n\n    /**\n     * Get the size of the stream in bytes. A value of -1 means that the size is\n     * not known.\n     *\n     * @return the size of the stream, or -1 if not specified\n     */\n    public long getSize() {\n        return APP_API.gst_app_src_get_size(this);\n    }\n\n    /**\n     * Set the stream type on appsrc . For seekable streams, the \"seek\" signal\n     * must be connected to.\n     *\n     * @param type stream type\n     */\n    public void setStreamType(AppSrc.StreamType type) {\n        APP_API.gst_app_src_set_stream_type(this, type);\n    }\n\n    /**\n     * Get the stream type set on the appsrc.\n     *\n     * @return stream type\n     */\n    public AppSrc.StreamType getStreamType() {\n        return APP_API.gst_app_src_get_stream_type(this);\n    }\n\n    /**\n     * Set the maximum amount of bytes that can be queued in appsrc . After the\n     * maximum amount of bytes are queued, appsrc will emit the \"enough-data\"\n     * signal.\n     *\n     * @param max number of bytes to queue\n     */\n    public void setMaxBytes(long max) {\n        APP_API.gst_app_src_set_max_bytes(this, max);\n    }\n\n    /**\n     * Get the maximum number of bytes that can be queued.\n     *\n     * @return maximum number of bytes\n     */\n    public long getMaxBytes() {\n        return APP_API.gst_app_src_get_max_bytes(this);\n    }\n\n    /**\n     * Configure the min and max latency in src . If min is set to -1, the\n     * default latency calculations for pseudo-live sources will be used.\n     *\n     * @param min the minimum latency\n     * @param max the maximum latency\n     */\n    public void setLatency(long min, long max) {\n        APP_API.gst_app_src_set_latency(this, min, max);\n    }\n\n    /**\n     * Get the latency. The returned value is a long array of length two, with\n     * min latency at index 0 and max latency at index 1.\n     *\n     * @return values as {@code long[]{min, max} }\n     */\n    public long[] getLatency() {\n        LongByReference minRef = new LongByReference();\n        LongByReference maxRef = new LongByReference();\n        APP_API.gst_app_src_get_latency(this, minRef, minRef);\n        return new long[]{minRef.getValue(), maxRef.getValue()};\n    }\n\n    /**\n     * Adds a buffer to the queue of buffers that the appsrc element will push\n     * to its source pad. This function takes ownership of the buffer.\n     * <p>\n     * When the block property is TRUE, this function can block until free space\n     * becomes available in the queue.\n     * \n     * @param buffer a {@link Buffer} to push\n     * @return GST_FLOW_OK when the buffer was successfully queued.\n     * GST_FLOW_FLUSHING when appsrc is not PAUSED or PLAYING. GST_FLOW_EOS when\n     * EOS occurred.\n     */\n    public FlowReturn pushBuffer(Buffer buffer) {\n        return APP_API.gst_app_src_push_buffer(this, buffer);\n    }\n\n    /**\n     * Indicates to the appsrc element that the last buffer queued in the\n     * element is the last buffer of the stream.\n     * \n     * @return GST_FLOW_OK when the EOS was successfuly queued. GST_FLOW_FLUSHING when\n     * appsrc is not PAUSED or PLAYING.\n     */\n    public FlowReturn endOfStream() {\n        return APP_API.gst_app_src_end_of_stream(this);\n    }\n\n    /**\n     * Signal that the source has enough data. It is recommended that the\n     * application stops calling push-buffer until the need-data signal is\n     * emitted again to avoid excessive buffer queueing.\n     */\n    public static interface ENOUGH_DATA {\n\n        /**\n         * Enough data signal\n         *\n         * @param elem the appsrc element that emitted the signal\n         */\n        public void enoughData(AppSrc elem);\n    }\n\n    /**\n     * Adds a listener for the <code>enough-data</code> signal\n     *\n     * @param listener Listener to be called this when appsrc fills its queue.\n     */\n    public void connect(final ENOUGH_DATA listener) {\n        connect(ENOUGH_DATA.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(AppSrc elem) {\n                listener.enoughData(elem);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>enough-data</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(ENOUGH_DATA listener) {\n        disconnect(ENOUGH_DATA.class, listener);\n    }\n\n    /**\n     * Signal that the source needs more data. In the callback or from another\n     * thread you should call push-buffer or end-of-stream.\n     * <p>\n     * length is just a hint and when it is set to -1, any number of bytes can\n     * be pushed into appsrc .\n     * <p>\n     * You can call push-buffer multiple times until the enough-data signal is\n     * fired.\n     */\n    public static interface NEED_DATA {\n\n        /**\n         * Need data signal\n         *\n         * @param elem the appsrc element that emitted the signal\n         * @param size the amount of bytes needed, or -1. This is just a hint.\n         */\n        public void needData(AppSrc elem, int size);\n    }\n\n    /**\n     * Adds a listener for the <code>need-data</code> signal\n     *\n     * @param listener Listener to be called when appsrc needs data.\n     */\n    public void connect(final NEED_DATA listener) {\n        connect(NEED_DATA.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(AppSrc elem, int size) {\n                listener.needData(elem, size);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>need-data</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(NEED_DATA listener) {\n        disconnect(NEED_DATA.class, listener);\n    }\n\n    /**\n     * Seek to the given offset, expressed in terms of the {@link Format} set on\n     * the AppSrc. The next push-buffer should produce buffers from the new\n     * offset . This callback is only called for seekable stream types.\n     */\n    public static interface SEEK_DATA {\n\n        /**\n         * Seek data signal.\n         *\n         * @param elem the appsrc element that emitted the signal\n         * @param position the offset to seek to, expressed in the\n         * {@link Format} set on the AppSrc\n         * @return true if the seek succeeded\n         */\n        public boolean seekData(AppSrc elem, long position);\n    }\n\n    /**\n     * Adds a listener for the <code>seek-data</code> signal\n     *\n     * @param listener listener to be called when a seek is requested\n     */\n    public void connect(final SEEK_DATA listener) {\n        connect(SEEK_DATA.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public boolean callback(AppSrc elem, long position) {\n                return listener.seekData(elem, position);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>seek-data</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(SEEK_DATA listener) {\n        disconnect(SEEK_DATA.class, listener);\n    }\n\n    /**\n     * The stream type.\n     * <p>\n     * See upstream documentation at\n     * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-libs/html/gst-plugins-base-libs-appsrc.html#GstAppStreamType\"\n     * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-libs/html/gst-plugins-base-libs-appsrc.html#GstAppStreamType</a>\n     * <p>\n     */\n    public enum StreamType implements NativeEnum<StreamType> {\n        /**\n         * No seeking is supported in the stream, such as a live stream.\n         */\n        STREAM(0),\n        /**\n         * The stream is seekable but seeking might not be very fast, such as\n         * data from a webserver.\n         */\n        SEEKABLE(1),\n        /**\n         * The stream is seekable and seeking is fast, such as in a local file.\n         */\n        RANDOM_ACCESS(2);\n\n        private final int value;\n\n        private StreamType(int value) {\n            this.value = value;\n        }\n\n        @Override\n        public int intValue() {\n            return value;\n        }\n\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/elements/BaseSink.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.elements;\n\nimport org.freedesktop.gstreamer.Element;\n\n/**\n * A base class for sink elements.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstBaseSink.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstBaseSink.html</a>\n * <p>\n */\npublic class BaseSink extends Element {\n\n    public static final String GTYPE_NAME = \"GstBaseSink\";\n\n    protected BaseSink(Initializer init) {\n        super(init);\n    }\n\n    // @TODO review - all properties are available by set / get mechanism\n    // some other methods require the preroll lock, but we don't have a way to\n    // access. Methods for subclasses should probably be protected.\n    \n//    public FlowReturn doPreroll(MiniObject obj) {\n//        return BASESINK_API.gst_base_sink_do_preroll(this, obj);\n//    }\n//\n//    public FlowReturn waitPreroll() {\n//        return BASESINK_API.gst_base_sink_wait_preroll(this);\n//    }\n//\n//    public void setSync(boolean sync) {\n//        BASESINK_API.gst_base_sink_set_sync(this, sync);\n//    }\n//\n//    public boolean isSync() {\n//        return BASESINK_API.gst_base_sink_get_sync(this);\n//    }\n//\n//    public void setMaximumLateness(long lateness, TimeUnit units) {\n//        BASESINK_API.gst_base_sink_set_max_lateness(this, units.toNanos(lateness));\n//    }\n//\n//    public long getMaximumLateness(TimeUnit units) {\n//        return units.convert(BASESINK_API.gst_base_sink_get_max_lateness(this), TimeUnit.NANOSECONDS);\n//    }\n//\n//    public void setQOSEnabled(boolean qos) {\n//        BASESINK_API.gst_base_sink_set_qos_enabled(this, qos);\n//    }\n//\n//    public boolean isQOSEnabled() {\n//        return BASESINK_API.gst_base_sink_is_qos_enabled(this);\n//    }\n//\n//    public void enableAsync(boolean enabled) {\n//        BASESINK_API.gst_base_sink_set_async_enabled(this, enabled);\n//    }\n//\n//    public boolean isAsync() {\n//        return BASESINK_API.gst_base_sink_is_async_enabled(this);\n//    }\n//\n//    public void setTsOffset(long offset) {\n//        BASESINK_API.gst_base_sink_set_ts_offset(this, offset);\n//    }\n//\n//    public long getTsOffset() {\n//        return BASESINK_API.gst_base_sink_get_ts_offset(this);\n//    }\n//\n//    public Buffer getLastBuffer() {\n//        return BASESINK_API.gst_base_sink_get_last_buffer(this);\n//    }\n//\n//    public void enableLastBuffer(boolean enable) {\n//        BASESINK_API.gst_base_sink_set_last_buffer_enabled(this, enable);\n//    }\n//\n//    public boolean isLastBufferEnabled() {\n//        return BASESINK_API.gst_base_sink_is_last_buffer_enabled(this);\n//    }\n//\n//    public boolean queryLatency(boolean live, boolean upstream_live, ClockTime min_latency, ClockTime max_latency) {\n//        return BASESINK_API.gst_base_sink_query_latency(this, live, upstream_live, min_latency, max_latency);\n//    }\n//\n//    public ClockTime getLatency() {\n//        return BASESINK_API.gst_base_sink_get_latency(this);\n//    }\n//\n//    public void setRenderDelay(ClockTime delay) {\n//        BASESINK_API.gst_base_sink_set_render_delay(this, delay);\n//    }\n//\n//    public ClockTime getRenderDelay() {\n//        return BASESINK_API.gst_base_sink_get_render_delay(this);\n//    }\n//\n//    public void setBlocksize(int blocksize) {\n//        BASESINK_API.gst_base_sink_set_blocksize(this, blocksize);\n//    }\n//\n//    public int getBlocksize() {\n//        return BASESINK_API.gst_base_sink_get_blocksize(this);\n//    }\n//\n//    public ClockReturn waitClock(ClockTime time, /* GstClockTimeDiff */ Pointer jitter) {\n//        return BASESINK_API.gst_base_sink_wait_clock(this, time, jitter);\n//    }\n//\n//    public FlowReturn waitEOS(ClockTime time, /* GstClockTimeDiff */ Pointer jitter) {\n//        return BASESINK_API.gst_base_sink_wait_eos(this, time, jitter);\n//    }\n\n//    @TODO work out strategy for overriding methods\n//    \n//    /**\n//     * Signal emitted when this {@link BaseSink} received a {@link ProposeAllocation} query.\n//     *\n//     * @see #setProposeAllocationHandler(ProposeAllocationHandler)\n//     */\n//    public static interface ProposeAllocationHandler {\n//    \tpublic boolean proposeAllocation(BaseSink sink, AllocationQuery query);    \t\n//    }\n//    \n//    /**\n//     * Set a handler for the {@link ProposeAllocation} query on this sink\n//     *\n//     * @param handler The handler to be called when a {@link ProposeAllocation} is received.\n//     */\n//    public void setProposeAllocationHandler(final ProposeAllocationHandler handler) {\n//        GstBaseSinkStruct struct = new GstBaseSinkStruct(handle());\n//        struct.readField(\"element\");\n//        GstBaseSinkClass basesinkClass = new GstBaseSinkClass(struct.element.object.object.g_type_instance.g_class.getPointer());\n//        basesinkClass.propose_allocation = new ProposeAllocation() {\n//\t\t\t@Override\n//\t\t\tpublic boolean callback(BaseSink sink, AllocationQuery query) {\n//\t\t\t\treturn handler.proposeAllocation(sink, query);\n//\t\t\t}\n//        };\n//        basesinkClass.writeField(\"propose_allocation\");\n//    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/elements/BaseSrc.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.elements;\n\nimport org.freedesktop.gstreamer.Element;\n\n/**\n * A base class for source elements.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstBaseSrc.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstBaseSrc.html</a>\n * <p>\n */\npublic class BaseSrc extends Element {\n    \n    public static final String GTYPE_NAME = \"GstBaseSrc\";\n\n    protected BaseSrc(Initializer init) {\n        super(init);\n    }\n\n    // @TODO review - all properties are available by set / get mechanism\n    // some other methods require the stream lock, but we don't have a way to\n    // access. Methods for subclasses should probably be protected.\n    \n//    public FlowReturn waitPlaying() {\n//    \treturn gst().gst_base_src_wait_playing(this);\n//    }\n//    public void setLive(boolean live) {\n//    \tgst().gst_base_src_set_live(this, live);\n//    }\n//    public boolean isLive() {\n//        return gst().gst_base_src_is_live(this);\n//    }\n//    public void setFormat(Format format) {\n//    \tgst().gst_base_src_set_format(this, format);\n//    }\n//    public boolean queryLatency(boolean[] live, ClockTime[] min_latency, ClockTime[] max_latency) {\n//    \treturn gst().gst_base_src_query_latency(this, live, min_latency, max_latency);\n//    }\n//    public void setBlocksize(long blocksize) {\n//    \tgst().gst_base_src_set_blocksize(this, blocksize);\n//    }\n//    public long getBlocksize() {\n//    \treturn gst().gst_base_src_get_blocksize(this);\n//    }\n//    public void setTimestamp(boolean timestamp) {\n//    \tgst().gst_base_src_set_do_timestamp(this, timestamp);\n//    }\n//    public boolean getTimestamp() {\n//    \treturn gst().gst_base_src_get_do_timestamp(this);\n//    }\n//    public boolean newSeamlessSegment(long start, long stop, long position) {\n//    \treturn gst().gst_base_src_new_seamless_segment(this, start, stop, position);\n//    }\n//    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/elements/BaseTransform.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.elements;\n\nimport org.freedesktop.gstreamer.Element;\n\n/**\n * A base class for simple transform filters.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstBaseTransform.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstBaseTransform.html</a>\n * <p>\n */\npublic class BaseTransform extends Element {\n    \n    public static final String GTYPE_NAME = \"GstBaseTransform\";\n\n    protected BaseTransform(Initializer init) {\n        super(init);\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/elements/DecodeBin.java",
    "content": "/*\n * Copyright (c) 2025 Neil C Smith\n * Copyright (c) 2016 Christophe Lafolet\n * Copyright (c) 2010 DHoyt <david.g.hoyt@gmail.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.elements;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Optional;\nimport org.freedesktop.gstreamer.Bin;\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.Element;\nimport org.freedesktop.gstreamer.ElementFactory;\nimport org.freedesktop.gstreamer.Pad;\nimport org.freedesktop.gstreamer.glib.NativeEnum;\nimport org.freedesktop.gstreamer.query.Query;\nimport org.freedesktop.gstreamer.lowlevel.GValueAPI.GValueArray;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback;\nimport org.freedesktop.gstreamer.lowlevel.GType;\nimport org.freedesktop.gstreamer.lowlevel.GValueAPI;\n\n/**\n * A {@link Bin} that auto-magically constructs a decoding pipeline using\n * available decoders and demuxers via auto-plugging.\n * <p>\n * {@link URIDecodeBin} uses DecodeBin internally and is often more convenient\n * to use, as it creates a suitable source element as well.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-plugins/html/gst-plugins-base-plugins-decodebin.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-plugins/html/gst-plugins-base-plugins-decodebin.html</a>\n * <p>\n */\npublic class DecodeBin extends Bin {\n\n    public static final String GST_NAME = \"decodebin\";\n    public static final String GTYPE_NAME = \"GstDecodeBin\";\n\n    /**\n     * Creates a new DecodeBin.\n     *\n     * @param name The name used to identify this DecodeBin.\n     */\n    public DecodeBin(String name) {\n        super(makeRawElement(GST_NAME, name));\n    }\n\n    DecodeBin(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Signal is emitted when a pad for which there is no further possible\n     * decoding is added to the {@link DecodeBin}.\n     */\n    public static interface UNKNOWN_TYPE {\n\n        /**\n         * @param element The element which has the new Pad.\n         * @param pad the new Pad.\n         * @param caps the caps of the pad that cannot be resolved.\n         */\n        public void unknownType(DecodeBin element, Pad pad, Caps caps);\n    }\n\n    /**\n     * Adds a listener for the <code>unknown-type</code> signal\n     *\n     * @param listener Listener to be called\n     */\n    public void connect(final UNKNOWN_TYPE listener) {\n        connect(UNKNOWN_TYPE.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(DecodeBin elem, Pad pad, Caps caps) {\n                listener.unknownType(elem, pad, caps);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>unknown-type</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(UNKNOWN_TYPE listener) {\n        disconnect(UNKNOWN_TYPE.class, listener);\n    }\n\n    /**\n     * Signal is emitted when a pad for which there is no further possible\n     * decoding is added to the {@link DecodeBin}.\n     */\n    public static interface AUTOPLUG_CONTINUE {\n\n        /**\n         * Autoplug continue signal.\n         *\n         * @param element The element which has the new Pad.\n         * @param pad the new Pad.\n         * @param caps the caps of the pad that cannot be resolved.\n         * @return TRUE if you wish decodebin to look for elements that can\n         * handle the given caps . If FALSE, those caps will be considered as\n         * final and the pad will be exposed as such (see 'pad-added' signal of\n         * {@link Element}).\n         */\n        public boolean autoplugContinue(DecodeBin element, Pad pad, Caps caps);\n    }\n\n    /**\n     * Adds a listener for the <code>autoplug-continue</code> signal\n     *\n     * @param listener Listener to be called\n     */\n    public void connect(final AUTOPLUG_CONTINUE listener) {\n        connect(AUTOPLUG_CONTINUE.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public boolean callback(DecodeBin elem, Pad pad, Caps caps) {\n                return listener.autoplugContinue(elem, pad, caps);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>autoplug-continue</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(AUTOPLUG_CONTINUE listener) {\n        disconnect(AUTOPLUG_CONTINUE.class, listener);\n    }\n\n    /**\n     * This function is emitted when an array of possible factories for caps on\n     * pad is needed. {@link DecodeBin} will by default return an array with all\n     * compatible factories, sorted by rank.\n     * <p>\n     * If this function returns {@link Optional#empty()}, pad will be exposed as\n     * a final caps.\n     * <p>\n     * If this function returns an empty list, the pad will be considered as\n     * having an unhandled type media type.\n     */\n    public static interface AUTOPLUG_FACTORIES {\n\n        /**\n         * @param element The element which has the new Pad.\n         * @param pad the new Pad.\n         * @param caps the caps of the pad that cannot be resolved.\n         * @return\n         */\n        public Optional<List<ElementFactory>> autoplugFactories(DecodeBin element, Pad pad, Caps caps);\n    }\n\n    /**\n     * Adds a listener for the <code>autoplug-factories</code> signal\n     *\n     * @param listener Listener to be called\n     */\n    public void connect(final AUTOPLUG_FACTORIES listener) {\n        connect(AUTOPLUG_FACTORIES.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public GValueArray callback(DecodeBin elem, Pad pad, Caps caps) {\n                Optional<List<ElementFactory>> factories\n                        = listener.autoplugFactories(elem, pad, caps);\n                return factories.map(list -> {\n                    GValueArray array = new GValueArray(list.size(), false);\n                    list.forEach(factory -> array.append(new GValueAPI.GValue(GType.OBJECT, factory)));\n                    return array;\n                }).orElse(null);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>autoplug-factories</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(AUTOPLUG_FACTORIES listener) {\n        disconnect(AUTOPLUG_FACTORIES.class, listener);\n    }\n\n    /**\n     * Once {@link DecodeBin} has found the possible ElementFactory objects to\n     * try for caps on pad, this signal is emitted. The purpose of the signal is\n     * for the application to perform additional sorting or filtering on the\n     * element factory array.\n     *\n     * The callee should copy and modify factories.\n     */\n    public static interface AUTOPLUG_SORT {\n\n        /**\n         * Autoplug sort\n         *\n         * @param element The element which has the new Pad\n         * @param pad the new Pad\n         * @param caps the caps of the pad that cannot be resolved\n         * @param factories A List of possible {@link ElementFactory} to use\n         * @return resorted list or {@link Optional#empty()}\n         */\n        public Optional<List<ElementFactory>> autoplugSort(\n                DecodeBin element, Pad pad, Caps caps, List<ElementFactory> factories);\n    }\n\n    /**\n     * Adds a listener for the <code>autoplug-sort</code> signal\n     *\n     * @param listener Listener to be called\n     */\n    public void connect(final AUTOPLUG_SORT listener) {\n        connect(AUTOPLUG_SORT.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public GValueArray callback(DecodeBin elem, Pad pad, Caps caps, GValueArray factories) {\n                int size = factories.getNValues();\n                List<ElementFactory> list = new ArrayList<>(size);\n                for (int i = 0; i < size; i++) {\n                    Object factory = factories.getValue(i);\n                    if (factory instanceof ElementFactory) {\n                        list.add((ElementFactory) factory);\n                    }\n                }\n                Optional<List<ElementFactory>> response\n                        = listener.autoplugSort(elem, pad, caps, list);\n                return response.map(l -> {\n                    GValueArray array = new GValueArray(l.size(), false);\n                    list.forEach(factory -> array.append(new GValueAPI.GValue(GType.OBJECT, factory)));\n                    return array;\n                }).orElse(null);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>autoplug-sort</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(AUTOPLUG_SORT listener) {\n        disconnect(AUTOPLUG_SORT.class, listener);\n    }\n\n    public enum AutoplugSelectResult implements NativeEnum<AutoplugSelectResult> {\n        TRY(0),\n        EXPOSE(1),\n        SKIP(2);\n\n        AutoplugSelectResult(final int value) {\n            this.value = value;\n        }\n\n        /**\n         * Gets the integer value of the enum.\n         *\n         * @return The integer value for this enum.\n         */\n        @Override\n        public int intValue() {\n            return value;\n        }\n        private final int value;\n    }\n\n    /**\n     * Once {@link DecodeBin} has found the possible ElementFactory objects to\n     * try for caps on pad, this signal is emitted. The purpose of the signal is\n     * for the application to perform additional filtering on the element\n     * factory array.\n     * <p>\n     * The signal handler should return a {@link AutoplugSelectResult} value\n     * indicating what decodebin should do next.\n     * <p>\n     * A value of {@link AutoplugSelectResult#TRY} will try to autoplug an\n     * element from factory.\n     * <p>\n     * A value of {@link AutoplugSelectResult#EXPOSE} will expose pad without\n     * plugging any element to it.\n     * <p>\n     * A value of {@link AutoplugSelectResult#SKIP} will skip factory and move\n     * to the next factory.\n     */\n    public static interface AUTOPLUG_SELECT {\n\n        /**\n         * @param element The decodebin\n         * @param pad the new Pad\n         * @param caps the caps of the pad\n         * @param factory the {@link ElementFactory} to use\n         * @return an {@link AutoplugSelectResult} that indicates the required\n         * operation. the default handler will always return\n         * {@link AutoplugSelectResult#TRY}\n         */\n        public AutoplugSelectResult autoplugSelect(final DecodeBin element, final Pad pad, final Caps caps, final ElementFactory factory);\n    }\n\n    /**\n     * Adds a listener for the <code>autoplug-select</code> signal\n     *\n     * @param listener Listener to be called\n     */\n    public void connect(final AUTOPLUG_SELECT listener) {\n        connect(AUTOPLUG_SELECT.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public AutoplugSelectResult callback(final DecodeBin elem, final Pad pad, final Caps caps, final ElementFactory factory) {\n                return listener.autoplugSelect(elem, pad, caps, factory);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>autoplug-select</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(final AUTOPLUG_SELECT listener) {\n        disconnect(AUTOPLUG_SELECT.class, listener);\n    }\n\n    /**\n     * This signal is emitted whenever an autoplugged element that is not linked\n     * downstream yet and not exposed does a query. It can be used to tell the\n     * element about the downstream supported caps for example..\n     */\n    public static interface AUTOPLUG_QUERY {\n\n        /**\n         * @param element the decodebin.\n         * @param pad the pad.\n         * @param child the child element doing the query\n         * @param query the query.\n         */\n        public boolean autoplugQuery(DecodeBin element, Pad pad, Element child, Query query);\n    }\n\n    /**\n     * Adds a listener for the <code>autoplug-query</code> signal\n     *\n     * @param listener Listener to be called\n     */\n    public void connect(final AUTOPLUG_QUERY listener) {\n        connect(AUTOPLUG_QUERY.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public boolean callback(DecodeBin elem, Pad pad, Element child, Query query) {\n                return listener.autoplugQuery(elem, pad, child, query);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>autoplug-query</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(AUTOPLUG_QUERY listener) {\n        disconnect(AUTOPLUG_QUERY.class, listener);\n    }\n\n    /**\n     * This signal is emitted once {@link DecodeBin} has finished decoding all\n     * the data.\n     */\n    public static interface DRAINED {\n\n        /**\n         * @param element The element\n         */\n        public void drained(DecodeBin element);\n    }\n\n    /**\n     * Adds a listener for the <code>drained</code> signal\n     *\n     * @param listener Listener to be called\n     */\n    public void connect(final DRAINED listener) {\n        connect(DRAINED.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(DecodeBin elem) {\n                listener.drained(elem);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>drained</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(DRAINED listener) {\n        disconnect(DRAINED.class, listener);\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/elements/Elements.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.elements;\n\nimport java.util.stream.Stream;\nimport org.freedesktop.gstreamer.glib.NativeObject;\nimport static org.freedesktop.gstreamer.glib.Natives.registration;\n\n/**\n *\n * @author Neil C Smith - https://www.neilcsmith.net\n */\npublic class Elements implements NativeObject.TypeProvider {\n\n    @Override\n    public Stream<NativeObject.TypeRegistration<?>> types() {\n        return Stream.of(\n                registration(AppSink.class, AppSink.GTYPE_NAME, AppSink::new),\n                registration(AppSrc.class, AppSrc.GTYPE_NAME, AppSrc::new),\n                registration(BaseSrc.class, BaseSrc.GTYPE_NAME, BaseSrc::new),\n                registration(BaseSink.class, BaseSink.GTYPE_NAME, BaseSink::new),\n                registration(BaseTransform.class, BaseTransform.GTYPE_NAME, BaseTransform::new),\n                registration(DecodeBin.class, DecodeBin.GTYPE_NAME, DecodeBin::new),\n                registration(PlayBin.class, PlayBin.GTYPE_NAME, PlayBin::new),\n                registration(URIDecodeBin.class, URIDecodeBin.GTYPE_NAME, URIDecodeBin::new));\n\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/elements/PlayBin.java",
    "content": "/*\n * Copyright (c) 2021 Neil C Smith\n * Copyright (c) 2014 Tom Greenwood <tgreenwood@cafex.com>\n * Copyright (c) 2009 Andres Colubri\n * Copyright (c) 2007 Wayne Meissner\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.elements;\n\nimport java.io.File;\nimport java.net.URI;\nimport java.util.EnumSet;\nimport java.util.Set;\nimport org.freedesktop.gstreamer.Bus;\n\nimport org.freedesktop.gstreamer.Element;\nimport org.freedesktop.gstreamer.Format;\nimport org.freedesktop.gstreamer.Gst;\nimport org.freedesktop.gstreamer.Pad;\nimport org.freedesktop.gstreamer.Pipeline;\nimport org.freedesktop.gstreamer.TagList;\nimport org.freedesktop.gstreamer.glib.NativeFlags;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback;\n\n/**\n * <p>\n * Playbin provides a stand-alone everything-in-one abstraction for an audio\n * and/or video player.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/documentation/playback/playbin.html\"\n * >https://gstreamer.freedesktop.org/documentation/playback/playbin.html</a>\n * <p>\n * <p>\n * It can handle both audio and video files and features\n * </p>\n * <ul>\n * <li>\n * automatic file type recognition and based on that automatic selection and\n * usage of the right audio/video/subtitle demuxers/decoders\n * </li>\n * <li>\n * visualisations for audio files\n * </li>\n * <li>\n * subtitle support for video files. Subtitles can be store in external files.\n * </li>\n * <li>\n * stream selection between different video/audio/subtitles streams\n * </li>\n * <li>\n * meta info (tag) extraction\n * </li>\n * <li>\n * easy access to the last video frame\n * </li>\n * <li>\n * buffering when playing streams over a network\n * </li>\n * <li>\n * volume control with mute option\n * </li>\n * </ul>\n * <p>\n * playbin is a {@link Pipeline}. It will notify the application of everything\n * that's happening (errors, end of stream, tags found, state changes, etc.) by\n * posting messages on its {@link Bus}. The application needs to watch the bus.\n * <p>\n * Playback can be initiated by setting the playbin to PLAYING state using\n * {@link #setState setState} or {@link #play play}. Note that the state change\n * will take place in the background in a separate thread, when the function\n * returns playback is probably not happening yet and any errors might not have\n * occured yet. Applications using playbin should ideally be written to deal\n * with things completely asynchroneous.\n * <p>\n * When playback has finished (an EOS message has been received on the bus) or\n * an error has occured (an ERROR message has been received on the bus) or the\n * user wants to play a different track, playbin should be set back to READY or\n * NULL state, then the input file/URI should be set to the new location and\n * then playbin be set to PLAYING state again.\n * <p>\n * Seeking can be done using {@link #seek seek} on the playbin element. Again,\n * the seek will not be executed instantaneously, but will be done in a\n * background thread. When the seek call returns the seek will most likely still\n * be in process. An application may wait for the seek to finish (or fail) using\n * {@link #getState(long)} with -1 as the timeout, but this will block the user\n * interface and is not recommended at all.\n * <p>\n * Applications may query the current position and duration of the stream via\n * {@link #queryPosition} and {@link #queryDuration} and setting the format\n * passed to {@link Format#TIME}. If the query was successful, the duration or\n * position will have been returned in units of nanoseconds.\n */\npublic class PlayBin extends Pipeline {\n\n    public static final String GST_NAME = \"playbin\";\n    public static final String GTYPE_NAME = \"GstPlayBin\";\n\n    /**\n     * Creates a new PlayBin.\n     *\n     * @param name The name used to identify this pipeline.\n     */\n    public PlayBin(String name) {\n        this(makeRawElement(GST_NAME, name));\n    }\n\n    /**\n     * Creates a new PlayBin.\n     *\n     * @param name The name used to identify this pipeline.\n     * @param uri The URI of the media file to load.\n     */\n    public PlayBin(String name, URI uri) {\n        this(name);\n        setURI(uri);\n    }\n\n    /**\n     * Creates a new PlayBin proxy.\n     *\n     * @param init proxy initialization args\n     *\n     */\n    PlayBin(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Sets the media file to play.\n     *\n     * @param file The {@link java.io.File} to play.\n     */\n    public void setInputFile(File file) {\n        setURI(file.toURI());\n    }\n\n    /**\n     * Sets the media URI to play.\n     *\n     * @param uri The {@link java.net.URI} to play.\n     */\n    public void setURI(URI uri) {\n        set(\"uri\", uri);\n    }\n\n    /**\n     * Sets the audio output Element.\n     * <p>\n     * To disable audio output, call this method with a <tt>null</tt> argument.\n     *\n     * @param element The element to use for audio output.\n     */\n    public void setAudioSink(Element element) {\n        setElement(\"audio-sink\", element);\n    }\n\n    /**\n     * Sets the video output Element.\n     * <p>\n     * To disable video output, call this method with a <tt>null</tt> argument.\n     *\n     * @param element The element to use for video output.\n     */\n    public void setVideoSink(Element element) {\n        setElement(\"video-sink\", element);\n    }\n\n    /**\n     * Sets the text output Element.\n     * <p>\n     * To disable text output, call this method with a <tt>null</tt> argument.\n     *\n     * @param element The element to use for text output.\n     */\n    public void setTextSink(Element element) {\n        setElement(\"text-sink\", element);\n    }\n\n    /**\n     * Sets the visualization output Element.\n     *\n     * @param element The element to use for visualization.\n     */\n    public void setVisualization(Element element) {\n        setElement(\"vis-plugin\", element);\n    }\n\n    /**\n     * Sets an output {@link Element} on the PlayBin.\n     *\n     * @param key The name of the output to change.\n     * @param element The Element to set as the output.\n     */\n    private void setElement(String key, Element element) {\n        set(key, element);\n    }\n\n    /**\n     * Set the flags to control the behaviour of this PlayBin.\n     * <p>\n     * The default value is\n     * soft-colorbalance+deinterlace+soft-volume+text+audio+video\n     * <p>\n     * See individual {@link PlayFlags} value descriptions for more information.\n     *\n     * @param flags set of {@link PlayFlags}\n     */\n    public void setFlags(Set<PlayFlags> flags) {\n        set(\"flags\", NativeFlags.toInt(flags));\n    }\n\n    /**\n     * Get the current flags set on this PlayBin. The returned set will be\n     * writable so that it can be altered and passed back to\n     * {@link #setFlags(java.util.Set)}.\n     *\n     * @return set of current {@link PlayFlags}\n     */\n    public Set<PlayFlags> getFlags() {\n        Object flags = get(\"flags\");\n        if (flags instanceof Number) {\n            return NativeFlags.fromInt(PlayFlags.class,\n                    ((Number) flags).intValue());\n        } else {\n            return EnumSet.noneOf(PlayFlags.class);\n        }\n    }\n\n    /**\n     * Sets the audio playback volume.\n     *\n     * @param volume value between 0.0 and 1.0 with 1.0 being full volume.\n     */\n    public void setVolume(double volume) {\n        set(\"volume\", Math.max(Math.min(volume, 1d), 0d));\n    }\n\n    /**\n     * Gets the current volume.\n     *\n     * @return The current volume as a percentage between 0 and 100 of the max\n     * volume.\n     */\n    public double getVolume() {\n        return ((Number) get(\"volume\")).doubleValue();\n    }\n\n    /**\n     * Get the currently playing audio stream. By default the first audio stream\n     * with data is played. Default value: -1\n     *\n     * @return the currently playing audio stream index (index is zero based).\n     */\n    public int getCurrentAudio() {\n        return (Integer) get(\"current-audio\");\n    }\n\n    /**\n     * Set the currently playing audio stream. By default the first audio stream\n     * with data is played.\n     *\n     * @param n audio stream index to switch to (index is zero based).\n     */\n    public void setCurrentAudio(int n) {\n        set(\"current-audio\", n);\n    }\n\n    /**\n     * Get the total number of available audio streams.\n     *\n     * @return total number of available audio streams\n     */\n    public int getNAudio() {\n        return (Integer) get(\"n-audio\");\n    }\n\n    /**\n     * Retrieve the stream-combiner sinkpad for a specific text stream. This pad\n     * can be used for notifications of caps changes, stream-specific queries,\n     * etc.\n     *\n     * @param audioStreamIndex a text stream number\n     * @return a GstPad, or NULL when the stream number does not exist.\n     */\n    public Pad getAudioPad(int audioStreamIndex) {\n        return emit(Pad.class, \"get-audio-pad\", audioStreamIndex);\n    }\n\n    /**\n     * Retrieve the tags of a specific audio stream number. This information can\n     * be used to select a stream.\n     *\n     * @param audioStreamIndex an audio stream number\n     * @return a GstTagList with tags or {@code null} when the stream number\n     * does not exist.\n     */\n    public TagList getAudioTags(int audioStreamIndex) {\n        return emit(TagList.class, \"get-audio-tags\", audioStreamIndex);\n    }\n\n    /**\n     * Get the currently playing text stream. By default the first text stream\n     * with data is played. Default value: -1\n     *\n     * @return the currently playing text stream index (index is zero based).\n     */\n    public int getCurrentText() {\n        return (Integer) get(\"current-text\");\n    }\n\n    /**\n     * Set the currently playing text stream. By default the first text stream\n     * with data is played.\n     *\n     * @param n text stream index to switch to (index is zero based).\n     */\n    public void setCurrentText(int n) {\n        set(\"current-text\", n);\n    }\n\n    /**\n     * Get the total number of available text streams.\n     *\n     * @return total number of available text streams\n     */\n    public int getNText() {\n        return (Integer) get(\"n-text\");\n    }\n\n    /**\n     * Retrieve the stream-combiner sinkpad for a specific text stream. This pad\n     * can be used for notifications of caps changes, stream-specific queries,\n     * etc.\n     *\n     * @param textStreamIndex a text stream number\n     * @return a GstPad, or {@code null} when the stream number does not exist.\n     */\n    public Pad getTextPad(int textStreamIndex) {\n        return emit(Pad.class, \"get-text-pad\", textStreamIndex);\n    }\n\n    /**\n     * Retrieve the tags of a specific text stream number. This information can\n     * be used to select a stream.\n     *\n     * @param textStreamIndex a text stream number\n     * @return a GstTagList with tags or {@code null} when the stream number\n     * does not exist.\n     */\n    public TagList getTextTags(int textStreamIndex) {\n        return emit(TagList.class, \"get-text-tags\", textStreamIndex);\n    }\n\n    /**\n     * Adds a listener for the <code>about-to-finish</code> signal\n     */\n    public void connect(final ABOUT_TO_FINISH listener) {\n        connect(ABOUT_TO_FINISH.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(PlayBin elem) {\n                listener.aboutToFinish(elem);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>about-to-finish</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(ABOUT_TO_FINISH listener) {\n        disconnect(ABOUT_TO_FINISH.class, listener);\n    }\n\n    /**\n     * Adds a listener for the <code>video-changed</code> signal\n     */\n    public void connect(final VIDEO_CHANGED listener) {\n        connect(VIDEO_CHANGED.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(PlayBin elem) {\n                listener.videoChanged(elem);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>video-changed</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(VIDEO_CHANGED listener) {\n        disconnect(VIDEO_CHANGED.class, listener);\n    }\n\n    /**\n     * Adds a listener for the <code>audio-changed</code> signal\n     */\n    public void connect(final AUDIO_CHANGED listener) {\n        connect(AUDIO_CHANGED.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(PlayBin elem) {\n                listener.audioChanged(elem);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>audio-changed</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(AUDIO_CHANGED listener) {\n        disconnect(AUDIO_CHANGED.class, listener);\n    }\n\n    /**\n     * Adds a listener for the <code>audio-changed</code> signal\n     */\n    public void connect(final TEXT_CHANGED listener) {\n        connect(TEXT_CHANGED.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(PlayBin elem) {\n                listener.textChanged(elem);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>text-changed</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(TEXT_CHANGED listener) {\n        disconnect(TEXT_CHANGED.class, listener);\n    }\n\n    /**\n     * Adds a listener for the <code>video-tags-changed</code> signal\n     */\n    public void connect(final VIDEO_TAGS_CHANGED listener) {\n        connect(VIDEO_TAGS_CHANGED.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(PlayBin elem, int stream) {\n                listener.videoTagsChanged(elem, stream);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>video-tags-changed</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(VIDEO_TAGS_CHANGED listener) {\n        disconnect(VIDEO_TAGS_CHANGED.class, listener);\n    }\n\n    /**\n     * Adds a listener for the <code>audio-tags-changed</code> signal\n     */\n    public void connect(final AUDIO_TAGS_CHANGED listener) {\n        connect(AUDIO_TAGS_CHANGED.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(PlayBin elem, int stream) {\n                listener.audioTagsChanged(elem, stream);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>audio-tags-changed</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(AUDIO_TAGS_CHANGED listener) {\n        disconnect(AUDIO_TAGS_CHANGED.class, listener);\n    }\n\n    /**\n     * Adds a listener for the <code>audio-tags-changed</code> signal\n     */\n    public void connect(final TEXT_TAGS_CHANGED listener) {\n        connect(TEXT_TAGS_CHANGED.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(PlayBin elem, int stream) {\n                listener.textTagsChanged(elem, stream);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>text-tags-changed</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(TEXT_TAGS_CHANGED listener) {\n        disconnect(TEXT_TAGS_CHANGED.class, listener);\n    }\n\n    /**\n     * Add a listener for the <code>element-setup</code> signal.\n     *\n     * @param listener listener to add\n     */\n    @Gst.Since(minor = 10)\n    public void connect(final ELEMENT_SETUP listener) {\n        Gst.checkVersion(1, 10);\n        connect(ELEMENT_SETUP.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(PlayBin playbin, Element element) {\n                listener.elementSetup(playbin, element);\n            }\n        });\n    }\n\n    /**\n     * Remove listener for the <code>element-setup</code> signal.\n     *\n     * @param listener listener to remove\n     */\n    @Gst.Since(minor = 10)\n    public void disconnect(ELEMENT_SETUP listener) {\n        disconnect(ELEMENT_SETUP.class, listener);\n    }\n\n    /**\n     * Add a listener for the <code>source-setup</code> signal.\n     *\n     * @param listener listener to add\n     */\n    public void connect(final SOURCE_SETUP listener) {\n        connect(SOURCE_SETUP.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(PlayBin playbin, Element element) {\n                listener.sourceSetup(playbin, element);\n            }\n        });\n    }\n\n    /**\n     * Remove listener for the <code>source-setup</code> signal.\n     *\n     * @param listener listener to remove\n     */\n    public void disconnect(SOURCE_SETUP listener) {\n        disconnect(SOURCE_SETUP.class, listener);\n    }\n\n    /**\n     * Signal emitted when the current uri is about to finish. You can set the\n     * uri and suburi to make sure that playback continues.\n     */\n    public static interface ABOUT_TO_FINISH {\n\n        /**\n         */\n        public void aboutToFinish(PlayBin element);\n    }\n\n    /**\n     * Signal is emitted whenever the number or order of the video streams has\n     * changed. The application will most likely want to select a new video\n     * stream.\n     */\n    public static interface VIDEO_CHANGED {\n\n        /**\n         */\n        public void videoChanged(PlayBin element);\n    }\n\n    /**\n     * Signal is emitted whenever the number or order of the audio streams has\n     * changed. The application will most likely want to select a new audio\n     * stream.\n     */\n    public static interface AUDIO_CHANGED {\n\n        /**\n         */\n        public void audioChanged(PlayBin element);\n    }\n\n    /**\n     * Signal is emitted whenever the number or order of the audio streams has\n     * changed. The application will most likely want to select a new audio\n     * stream.\n     */\n    public static interface TEXT_CHANGED {\n\n        /**\n         */\n        public void textChanged(PlayBin element);\n    }\n\n    /**\n     * Signal is emitted whenever the tags of a video stream have changed. The\n     * application will most likely want to get the new tags.\n     */\n    public static interface VIDEO_TAGS_CHANGED {\n\n        /**\n         * @param stream stream index with changed tags\n         */\n        public void videoTagsChanged(PlayBin element, int stream);\n    }\n\n    /**\n     * Signal is emitted whenever the tags of an audio stream have changed. The\n     * application will most likely want to get the new tags.\n     */\n    public static interface AUDIO_TAGS_CHANGED {\n\n        /**\n         * @param stream stream index with changed tags\n         */\n        public void audioTagsChanged(PlayBin element, int stream);\n    }\n\n    /**\n     * Signal is emitted whenever the tags of a text stream have changed. The\n     * application will most likely want to get the new tags.\n     */\n    public static interface TEXT_TAGS_CHANGED {\n\n        /**\n         * @param stream stream index with changed tags\n         */\n        public void textTagsChanged(PlayBin element, int stream);\n    }\n\n    /**\n     * This signal is emitted when a new element is added to playbin or any of\n     * its sub-bins. This signal can be used to configure elements, e.g. to set\n     * properties on decoders. This is functionally equivalent to connecting to\n     * the deep-element-added signal, but more convenient.\n     * <p>\n     * This signal is usually emitted from the context of a GStreamer streaming\n     * thread, so might be called at the same time as code running in the main\n     * application thread.\n     */\n    @Gst.Since(minor = 10)\n    public static interface ELEMENT_SETUP {\n\n        /**\n         * Element setup signal callback.\n         *\n         * @param playbin signal source\n         * @param element added element\n         */\n        public void elementSetup(PlayBin playbin, Element element);\n    }\n\n    /**\n     * This signal is emitted after the source element has been created, so it\n     * can be configured by setting additional properties (e.g. set a proxy\n     * server for an http source, or set the device and read speed for an audio\n     * cd source). This is functionally equivalent to connecting to the\n     * notify::source signal, but more convenient.\n     * <p>\n     * This signal is usually emitted from the context of a GStreamer streaming\n     * thread.\n     */\n    public static interface SOURCE_SETUP {\n\n        /**\n         * Source setup signal callback.\n         *\n         * @param playbin signal source\n         * @param element source element added\n         */\n        public void sourceSetup(PlayBin playbin, Element element);\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/elements/PlayFlags.java",
    "content": "/* \n * Copyright (c) 2021 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.elements;\n\nimport org.freedesktop.gstreamer.glib.NativeFlags;\n\n/**\n * Extra flags to configure the behaviour of the {@link PlayBin} sinks.\n */\npublic enum PlayFlags implements NativeFlags<PlayFlags> {\n\n    /**\n     * Enable rendering of the video stream.\n     */\n    VIDEO(1 << 0),\n    /**\n     * Enable rendering of the audio stream.\n     */\n    AUDIO(1 << 1),\n    /**\n     * Enable rendering of subtitles.\n     */\n    TEXT(1 << 2),\n    /**\n     * Enable rendering of visualisations when there is no video stream.\n     */\n    VIS(1 << 3),\n    /**\n     * Use software volume.\n     */\n    SOFT_VOLUME(1 << 4),\n    /**\n     * Only allow native audio formats, this omits configuration of audioconvert\n     * and audioresample.\n     */\n    NATIVE_AUDIO(1 << 5),\n    /**\n     * Only allow native video formats, this omits configuration of videoconvert\n     * and videoscale.\n     */\n    NATIVE_VIDEO(1 << 6),\n    /**\n     * Enable progressive download buffering for selected formats.\n     */\n    DOWNLOAD(1 << 7),\n    /**\n     * Enable buffering of the demuxed or parsed data.\n     */\n    BUFFERING(1 << 8),\n    /**\n     * Deinterlace raw video (if native not forced).\n     */\n    DEINTERLACE(1 << 9),\n    /**\n     * Use a software filter for colour balance.\n     */\n    SOFT_COLORBALANCE(1 << 10),\n    /**\n     * Force audio/video filters to be applied if set.\n     */\n    FORCE_FILTERS(1 << 11),\n    /**\n     * Force to use only software-based decoders ignoring those with hardware\n     * class.\n     */\n    FORCE_SW_DECODERS(1 << 12);\n\n    private final int value;\n\n    private PlayFlags(int value) {\n        this.value = value;\n    }\n\n    @Override\n    public int intValue() {\n        return value;\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/elements/URIDecodeBin.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2016 Christophe Lafolet\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.elements;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Optional;\nimport org.freedesktop.gstreamer.Bin;\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.Element;\nimport org.freedesktop.gstreamer.ElementFactory;\nimport org.freedesktop.gstreamer.Pad;\nimport org.freedesktop.gstreamer.glib.NativeEnum;\nimport org.freedesktop.gstreamer.query.Query;\nimport org.freedesktop.gstreamer.lowlevel.GValueAPI.GValueArray;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback;\nimport org.freedesktop.gstreamer.lowlevel.GType;\nimport org.freedesktop.gstreamer.lowlevel.GValueAPI;\n\n/**\n * A {@link Bin} that decodes data from a URI into raw media. It selects a\n * source element that can handle the given “uri” scheme and connects it to a\n * decodebin.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-plugins/html/gst-plugins-base-plugins-uridecodebin.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-plugins/html/gst-plugins-base-plugins-uridecodebin.html</a>\n * <p>\n */\npublic class URIDecodeBin extends Bin {\n\n    public static final String GST_NAME = \"uridecodebin\";\n    public static final String GTYPE_NAME = \"GstURIDecodeBin\";\n\n    public URIDecodeBin(final String name) {\n        this(makeRawElement(GST_NAME, name));\n    }\n\n    URIDecodeBin(final Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Signal is emitted when a pad for which there is no further possible\n     * decoding is added to the {@link URIDecodeBin}.\n     */\n    public static interface UNKNOWN_TYPE {\n\n        /**\n         * @param element The element which has the new Pad.\n         * @param pad the new Pad.\n         * @param caps the caps of the pad that cannot be resolved.\n         */\n        public void unknownType(URIDecodeBin element, Pad pad, Caps caps);\n    }\n\n    /**\n     * Adds a listener for the <code>unknown-type</code> signal\n     *\n     * @param listener Listener to be called\n     */\n    public void connect(final UNKNOWN_TYPE listener) {\n        connect(UNKNOWN_TYPE.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(URIDecodeBin elem, Pad pad, Caps caps) {\n                listener.unknownType(elem, pad, caps);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>unknown-type</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(UNKNOWN_TYPE listener) {\n        disconnect(UNKNOWN_TYPE.class, listener);\n    }\n\n    /**\n     * Signal is emitted when a pad for which there is no further possible\n     * decoding is added to the {@link URIDecodeBin}.\n     */\n    public static interface AUTOPLUG_CONTINUE {\n\n        /**\n         * Autoplug continue signal.\n         *\n         * @param element The element which has the new Pad.\n         * @param pad the new Pad.\n         * @param caps the caps of the pad that cannot be resolved.\n         * @return TRUE if you wish decodebin to look for elements that can\n         * handle the given caps . If FALSE, those caps will be considered as\n         * final and the pad will be exposed as such (see 'pad-added' signal of\n         * {@link Element}).\n         */\n        public boolean autoplugContinue(URIDecodeBin element, Pad pad, Caps caps);\n    }\n\n    /**\n     * Adds a listener for the <code>autoplug-continue</code> signal\n     *\n     * @param listener Listener to be called\n     */\n    public void connect(final AUTOPLUG_CONTINUE listener) {\n        connect(AUTOPLUG_CONTINUE.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public boolean callback(URIDecodeBin elem, Pad pad, Caps caps) {\n                return listener.autoplugContinue(elem, pad, caps);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>autoplug-continue</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(AUTOPLUG_CONTINUE listener) {\n        disconnect(AUTOPLUG_CONTINUE.class, listener);\n    }\n\n    /**\n     * This function is emitted when an array of possible factories for caps on\n     * pad is needed. {@link URIDecodeBin} will by default return an array with all\n     * compatible factories, sorted by rank.\n     * <p>\n     * If this function returns {@link Optional#EMPTY}, pad will be exposed as a\n     * final caps.\n     * <p>\n     * If this function returns an empty list, the pad will be considered as\n     * having an unhandled type media type.\n     */\n    public static interface AUTOPLUG_FACTORIES {\n\n        /**\n         * @param element The element which has the new Pad.\n         * @param pad the new Pad.\n         * @param caps the caps of the pad that cannot be resolved.\n         * @return\n         */\n        public Optional<List<ElementFactory>> autoplugFactories(URIDecodeBin element, Pad pad, Caps caps);\n    }\n\n    /**\n     * Adds a listener for the <code>autoplug-factories</code> signal\n     *\n     * @param listener Listener to be called\n     */\n    public void connect(final AUTOPLUG_FACTORIES listener) {\n        connect(AUTOPLUG_FACTORIES.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public GValueArray callback(URIDecodeBin elem, Pad pad, Caps caps) {\n                Optional<List<ElementFactory>> factories\n                        = listener.autoplugFactories(elem, pad, caps);\n                return factories.map(list -> {\n                    GValueArray array = new GValueArray(list.size(), false);\n                    list.forEach(factory -> array.append(new GValueAPI.GValue(GType.OBJECT, factory)));\n                    return array;\n                }).orElse(null);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>autoplug-factories</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(AUTOPLUG_FACTORIES listener) {\n        disconnect(AUTOPLUG_FACTORIES.class, listener);\n    }\n\n    /**\n     * Once {@link URIDecodeBin} has found the possible ElementFactory objects to\n     * try for caps on pad, this signal is emitted. The purpose of the signal is\n     * for the application to perform additional sorting or filtering on the\n     * element factory array.\n     *\n     * The callee should copy and modify factories.\n     */\n    public static interface AUTOPLUG_SORT {\n\n        /**\n         * Autoplug sort\n         *\n         * @param element The element which has the new Pad\n         * @param pad the new Pad\n         * @param caps the caps of the pad that cannot be resolved\n         * @param factories A List of possible {@link ElementFactory} to use\n         * @return resorted list or {@link Optional#EMPTY}\n         */\n        public Optional<List<ElementFactory>> autoplugSort(\n                URIDecodeBin element, Pad pad, Caps caps, List<ElementFactory> factories);\n    }\n\n    /**\n     * Adds a listener for the <code>autoplug-sort</code> signal\n     *\n     * @param listener Listener to be called\n     */\n    public void connect(final AUTOPLUG_SORT listener) {\n        connect(AUTOPLUG_SORT.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public GValueArray callback(URIDecodeBin elem, Pad pad, Caps caps, GValueArray factories) {\n                int size = factories.getNValues();\n                List<ElementFactory> list = new ArrayList<>(size);\n                for (int i = 0; i < size; i++) {\n                    Object factory = factories.getValue(i);\n                    if (factory instanceof ElementFactory) {\n                        list.add((ElementFactory) factory);\n                    }\n                }\n                Optional<List<ElementFactory>> response\n                        = listener.autoplugSort(elem, pad, caps, list);\n                return response.map(l -> {\n                    GValueArray array = new GValueArray(l.size(), false);\n                    list.forEach(factory -> array.append(new GValueAPI.GValue(GType.OBJECT, factory)));\n                    return array;\n                }).orElse(null);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>autoplug-sort</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(AUTOPLUG_SORT listener) {\n        disconnect(AUTOPLUG_SORT.class, listener);\n    }\n\n    public enum AutoplugSelectResult implements NativeEnum<AutoplugSelectResult> {\n        TRY(0),\n        EXPOSE(1),\n        SKIP(2);\n\n        AutoplugSelectResult(final int value) {\n            this.value = value;\n        }\n\n        /**\n         * Gets the integer value of the enum.\n         *\n         * @return The integer value for this enum.\n         */\n        @Override\n        public int intValue() {\n            return value;\n        }\n        private final int value;\n    }\n\n    /**\n     * Once {@link URIDecodeBin} has found the possible ElementFactory objects to\n     * try for caps on pad, this signal is emitted. The purpose of the signal is\n     * for the application to perform additional filtering on the element\n     * factory array.\n     * <p>\n     * The signal handler should return a {@link AutoplugSelectResult} value\n     * indicating what decodebin should do next.\n     * <p>\n     * A value of {@link AutoplugSelectResult#TRY} will try to autoplug an\n     * element from factory.\n     * <p>\n     * A value of {@link AutoplugSelectResult#EXPOSE} will expose pad without\n     * plugging any element to it.\n     * <p>\n     * A value of {@link AutoplugSelectResult#SKIP} will skip factory and move\n     * to the next factory.\n     */\n    public static interface AUTOPLUG_SELECT {\n\n        /**\n         * @param element The decodebin\n         * @param pad the new Pad\n         * @param caps the caps of the pad\n         * @param factory the {@link ElementFactory} to use\n         * @return an {@link AutoplugSelectResult} that indicates the required\n         * operation. the default handler will always return\n         * {@link AutoplugSelectResult#TRY}\n         */\n        public AutoplugSelectResult autoplugSelect(final URIDecodeBin element, final Pad pad, final Caps caps, final ElementFactory factory);\n    }\n\n    /**\n     * Adds a listener for the <code>autoplug-select</code> signal\n     *\n     * @param listener Listener to be called\n     */\n    public void connect(final AUTOPLUG_SELECT listener) {\n        connect(AUTOPLUG_SELECT.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public AutoplugSelectResult callback(final URIDecodeBin elem, final Pad pad, final Caps caps, final ElementFactory factory) {\n                return listener.autoplugSelect(elem, pad, caps, factory);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>autoplug-select</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(final AUTOPLUG_SELECT listener) {\n        disconnect(AUTOPLUG_SELECT.class, listener);\n    }\n\n    /**\n     * This signal is emitted whenever an autoplugged element that is not linked\n     * downstream yet and not exposed does a query. It can be used to tell the\n     * element about the downstream supported caps for example..\n     */\n    public static interface AUTOPLUG_QUERY {\n\n        /**\n         * @param element the decodebin.\n         * @param pad the pad.\n         * @param child the child element doing the query\n         * @param query the query.\n         */\n        public boolean autoplugQuery(URIDecodeBin element, Pad pad, Element child, Query query);\n    }\n\n    /**\n     * Adds a listener for the <code>autoplug-query</code> signal\n     *\n     * @param listener Listener to be called\n     */\n    public void connect(final AUTOPLUG_QUERY listener) {\n        connect(AUTOPLUG_QUERY.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public boolean callback(URIDecodeBin elem, Pad pad, Element child, Query query) {\n                return listener.autoplugQuery(elem, pad, child, query);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>autoplug-query</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(AUTOPLUG_QUERY listener) {\n        disconnect(AUTOPLUG_QUERY.class, listener);\n    }\n\n    /**\n     * This signal is emitted once {@link URIDecodeBin} has finished decoding all\n     * the data.\n     */\n    public static interface DRAINED {\n\n        /**\n         * @param element The element\n         */\n        public void drained(URIDecodeBin element);\n    }\n\n    /**\n     * Adds a listener for the <code>drained</code> signal\n     *\n     * @param listener Listener to be called\n     */\n    public void connect(final DRAINED listener) {\n        connect(DRAINED.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(URIDecodeBin elem) {\n                listener.drained(elem);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>drained</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(DRAINED listener) {\n        disconnect(DRAINED.class, listener);\n    }\n\n    /**\n     * Signal is emitted after the source has been created, so it can be\n     * configured by setting additionnal properties.\n     */\n    public static interface SOURCE_SETUP {\n\n        /**\n         *\n         * @param bin the container.\n         * @param elem the created source\n         */\n        public void sourceSetup(URIDecodeBin bin, Element elem);\n    }\n\n    /**\n     * Adds a listener for the <code>source-setup</code> signal\n     *\n     * @param source-setup Listener to be called\n     */\n    public void connect(final SOURCE_SETUP listener) {\n        this.connect(SOURCE_SETUP.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(final URIDecodeBin bin, final Element elem) {\n                listener.sourceSetup(bin, elem);\n            }\n        });\n    }\n\n    /**\n     * Removes a listener for the <code>source-setup</code> signal\n     *\n     * @param listener The listener that was previously added.\n     */\n    public void disconnect(final SOURCE_SETUP listener) {\n        this.disconnect(SOURCE_SETUP.class, listener);\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/event/BufferSizeEvent.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2008 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wim.taymans@chello.be>\n *                    2005 Wim Taymans <wim@fluendo.com>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.event;\n\nimport org.freedesktop.gstreamer.Format;\nimport org.freedesktop.gstreamer.glib.Natives;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API;\n\n/**\n * A buffersize event. The event is sent downstream and notifies elements that\n * they should provide a buffer of the specified dimensions.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-buffer-size\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-buffer-size</a>\n * <p>\n * When the async flag is set, a thread boundary is preferred.\n */\npublic class BufferSizeEvent extends Event {\n\n    /**\n     * This constructor is for internal use only.\n     *\n     * @param init initialization data.\n     */\n    BufferSizeEvent(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Creates a new buffersize event.\n     * <p>\n     * The event is sent downstream and notifies elements that they should\n     * provide a buffer of the specified dimensions.\n     * <p>\n     * When the <tt>async</tt> flag is set, a thread boundary is preferred.\n     *\n     * @param format buffer format\n     * @param minsize minimum buffer size\n     * @param maxsize maximum buffer size\n     * @param async thread behaviour\n     */\n    public BufferSizeEvent(Format format, long minsize, long maxsize, boolean async) {\n        super(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_buffer_size(format, minsize, maxsize, async)));\n    }\n\n    /**\n     * Gets the format of the buffersize event.\n     *\n     * @return the format.\n     */\n    public Format getFormat() {\n        Format[] format = new Format[1];\n        GSTEVENT_API.gst_event_parse_buffer_size(this, format, null, null, null);\n        return format[0];\n    }\n\n    /**\n     * Gets the minimum buffer size.\n     *\n     * @return the minimum buffer size.\n     */\n    public long getMinimumSize() {\n        long[] size = {0};\n        GSTEVENT_API.gst_event_parse_buffer_size(this, null, size, null, null);\n        return size[0];\n    }\n\n    /**\n     * Gets the maximum buffer size.\n     *\n     * @return the maximum buffer size.\n     */\n    public long getMaximumSize() {\n        long[] size = {0};\n        GSTEVENT_API.gst_event_parse_buffer_size(this, null, null, size, null);\n        return size[0];\n    }\n\n    /**\n     * Gets the preferred thread behaviour.\n     *\n     * @return <tt>true</tt> if a thread boundary is preferred.\n     */\n    public boolean isAsync() {\n        boolean[] async = {false};\n        GSTEVENT_API.gst_event_parse_buffer_size(this, null, null, null, async);\n        return async[0];\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/event/CapsEvent.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2016 Christophe Lafolet\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.event;\n\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API;\n\n/**\n * A CAPS event for {@link Caps}. The caps event can only travel downstream\n * synchronized with the buffer flow and contains the format of the buffers that\n * will follow after the event.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-caps\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-caps</a>\n * <p>\n */\npublic class CapsEvent extends Event {\n\n    /**\n     * This constructor is for internal use only.\n     *\n     * @param init initialization data.\n     */\n    CapsEvent(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Creates a new caps event.\n     */\n    public CapsEvent(final Caps caps) {\n        super(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_caps(caps)));\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/event/EOSEvent.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2008 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wim.taymans@chello.be>\n *                    2005 Wim Taymans <wim@fluendo.com>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.event;\n\nimport org.freedesktop.gstreamer.Bus;\nimport org.freedesktop.gstreamer.FlowReturn;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API;\n\n/**\n * End-Of-Stream event.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-eos\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-eos</a>\n * <p>\n * The eos event can only travel downstream synchronized with the buffer flow.\n * Elements that receive the EOS event on a pad can return\n * {@link FlowReturn#EOS} when data after the EOS event arrives.\n * <p>\n * The EOS event will travel down to the sink elements in the pipeline which\n * will then post the {@link Bus.EOS } message on the bus after they have\n * finished playing any buffered data.\n * <p>\n * When all sinks have posted an EOS message, an EOS message is forwarded to the\n * application.\n * <p>\n * The EOS event itself will not cause any state transitions of the pipeline.\n */\npublic class EOSEvent extends Event {\n\n    /**\n     * This constructor is for internal use only.\n     *\n     * @param init initialization data.\n     */\n    EOSEvent(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Creates a new EOS event.\n     */\n    public EOSEvent() {\n        super(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_eos()));\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/event/Event.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.event;\n\nimport java.util.EnumMap;\nimport java.util.Map;\nimport java.util.function.Function;\nimport java.util.stream.Stream;\nimport org.freedesktop.gstreamer.MiniObject;\nimport org.freedesktop.gstreamer.Structure;\nimport org.freedesktop.gstreamer.glib.NativeObject;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GstEventAPI;\nimport org.freedesktop.gstreamer.lowlevel.ReferenceManager;\nimport org.freedesktop.gstreamer.lowlevel.annotations.HasSubtype;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API;\n\n/**\n * Base type of all events.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html</a>\n * <p>\n * Events are passed between elements in parallel to the data stream. Some\n * events are serialized with buffers, others are not. Some events only travel\n * downstream, others only upstream. Some events can travel both upstream and\n * downstream.\n * <p>\n * The events are used to signal special conditions in the datastream such as\n * EOS (end of stream) or the start of a new stream-segment.\n * <p>\n * Events are also used to flush the pipeline of any pending data.\n *\n * @see Pad#pushEvent\n * @see Pad#sendEvent\n * @see Element#sendEvent\n */\n@HasSubtype\npublic class Event extends MiniObject {\n\n    public static final String GTYPE_NAME = \"GstEvent\";\n\n    private static final Map<EventType, Function<Initializer, Event>> TYPE_MAP\n            = new EnumMap<>(EventType.class);\n\n    static {\n        TYPE_MAP.put(EventType.BUFFERSIZE, BufferSizeEvent::new);\n        TYPE_MAP.put(EventType.EOS, EOSEvent::new);\n        TYPE_MAP.put(EventType.CAPS, CapsEvent::new);\n        TYPE_MAP.put(EventType.RECONFIGURE, ReconfigureEvent::new);\n        TYPE_MAP.put(EventType.STREAM_START, StreamStartEvent::new);\n        TYPE_MAP.put(EventType.LATENCY, LatencyEvent::new);\n        TYPE_MAP.put(EventType.FLUSH_START, FlushStartEvent::new);\n        TYPE_MAP.put(EventType.FLUSH_STOP, FlushStopEvent::new);\n        TYPE_MAP.put(EventType.NAVIGATION, NavigationEvent::new);\n        TYPE_MAP.put(EventType.SEGMENT, SegmentEvent::new);\n        TYPE_MAP.put(EventType.SEEK, SeekEvent::new);\n        TYPE_MAP.put(EventType.TAG, TagEvent::new);\n        TYPE_MAP.put(EventType.QOS, QOSEvent::new);\n        TYPE_MAP.put(EventType.STEP, StepEvent::new);\n    }\n\n    /**\n     * This constructor is for internal use only.\n     *\n     * @param init initialization data.\n     */\n    Event(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Gets the structure containing the data in this event.\n     *\n     * @return a structure.\n     */\n    public Structure getStructure() {\n        return ReferenceManager.addKeepAliveReference(GSTEVENT_API.gst_event_get_structure(this), this);\n    }\n\n    private static Event create(Initializer init) {\n        GstEventAPI.EventStruct struct = new GstEventAPI.EventStruct(init.ptr.getPointer());\n        EventType type = (EventType) struct.readField(\"type\");\n        return TYPE_MAP.getOrDefault(type, Event::new).apply(init);\n    }\n\n    public static class Types implements TypeProvider {\n\n        @Override\n        public Stream<TypeRegistration<?>> types() {\n            return Stream.of(\n                    Natives.registration(Event.class, GTYPE_NAME, Event::create)\n            );\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/event/EventType.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2008 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wim.taymans@chello.be>\n *                    2005 Wim Taymans <wim@fluendo.com>\n * \n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.event;\n\nimport org.freedesktop.gstreamer.Gst;\nimport org.freedesktop.gstreamer.glib.NativeEnum;\nimport org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue;\n\n/**\n * The standard event types that can be sent in a pipeline.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#GstEventType\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#GstEventType</a>\n * <p>\n * The custom event types can be used for private messages between elements\n * that can't be expressed using normal GStreamer buffer passing semantics. \n * <p>\n * Custom events carry an arbitrary {@link Structure}.  Specific custom events \n * are distinguished by the name of the structure.\n */\npublic enum EventType implements NativeEnum<EventType> {\n    /** Unknown event */\n    @DefaultEnumValue UNKNOWN(0, 0),\n\n    /* bidirectional events */\n    /**\n     * Start a flush operation. This event clears all data from the pipeline and\n     * unblock all streaming threads.\n     */\n    FLUSH_START(10, Flags.BOTH),\n    /**\n     * Stop a flush operation. This event resets the running-time of the\n     * pipeline.\n     */\n    FLUSH_STOP(20, Flags.BOTH | Flags.SERIALIZED),\n\n    /* downstream serialized events */\n    /**\n     * Event to mark the start of a new stream. Sent before any other serialized\n     * event and only sent at the start of a new stream, not after flushing\n     * seeks.\n     */\n    STREAM_START(40, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY),\n    /**\n     * #GstCaps event. Notify the pad of a new media type.\n     */\n    CAPS(50, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY),\n    /**\n     * A new media segment follows in the dataflow. The segment events contains\n     * information for clipping buffers and converting buffer timestamps to\n     * running-time and stream-time.\n     */\n    SEGMENT(70, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY),\n    /**\n     * A new #GstStreamCollection is available (Since 1.10)\n     */\n    @Gst.Since(minor = 10)\n    STREAM_COLLECTION(75, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY | Flags.STICKY_MULTI),\n    /**\n     * A new set of metadata tags has been found in the stream.\n     */\n    TAG(80, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY | Flags.STICKY_MULTI),\n    /**\n     * Notification of buffering requirements. Currently not used yet.\n     */\n    BUFFERSIZE(90, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY),\n    /**\n     * An event that sinks turn into a message. Used to send messages that\n     * should be emitted in sync with rendering.\n     */\n    SINK_MESSAGE(100, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY | Flags.STICKY_MULTI),\n    /**\n     * Indicates that there is no more data for the stream group ID in the\n     * message. Sent before EOS in some instances and should be handled mostly\n     * the same. (Since 1.10)\n     */\n    @Gst.Since(minor = 10)\n    STREAM_GROUP_DONE(105, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY),\n    /**\n     * End-Of-Stream. No more data is to be expected to follow without a SEGMENT\n     * event.\n     */\n    EOS(110, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY),\n    /**\n     * An event which indicates that a new table of contents (TOC) was found or\n     * updated.\n     */\n    TOC(120, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY | Flags.STICKY_MULTI),\n    /**\n     * An event which indicates that new or updated encryption information has\n     * been found in the stream.\n     */\n    PROTECTION(130, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY | Flags.STICKY_MULTI),\n\n    /* non-sticky downstream serialized */\n    /**\n     * Marks the end of a segment playback.\n     */\n    SEGMENT_DONE(150, Flags.DOWNSTREAM | Flags.SERIALIZED),\n    /**\n     * Marks a gap in the datastream.\n     */\n    GAP(160, Flags.DOWNSTREAM | Flags.SERIALIZED),\n\n    /* upstream events */\n    /**\n     * A quality message. Used to indicate to upstream elements that the\n     * downstream elements should adjust their processing rate.\n     */\n    QOS(190, Flags.UPSTREAM),\n    /**\n     * A request for a new playback position and rate.\n     */\n    SEEK(200, Flags.UPSTREAM),\n    /**\n     * Navigation events are usually used for communicating user requests, such\n     * as mouse or keyboard movements, to upstream elements.\n     */\n    NAVIGATION(210, Flags.UPSTREAM),\n    /**\n     * Notification of new latency adjustment. Sinks will use the latency\n     * information to adjust their synchronisation.\n     */\n    LATENCY(220, Flags.UPSTREAM),\n    /**\n     * A request for stepping through the media. Sinks will usually execute the\n     * step operation.\n     */\n    STEP(230, Flags.UPSTREAM),\n    /**\n     * A request for upstream renegotiating caps and reconfiguring.\n     */\n    RECONFIGURE(240, Flags.UPSTREAM),\n    /**\n     * A request for a new playback position based on TOC entry's UID.\n     */\n    TOC_SELECT(250, Flags.UPSTREAM),\n    /**\n     * A request to select one or more streams (Since 1.10)\n     */\n    @Gst.Since(minor = 10)\n    SELECT_STREAMS(260, Flags.UPSTREAM),\n    /* custom events start here */\n    /**\n     * Upstream custom event\n     */\n    CUSTOM_UPSTREAM(270, Flags.UPSTREAM),\n    /**\n     * Downstream custom event that travels in the data flow.\n     */\n    CUSTOM_DOWNSTREAM(280, Flags.DOWNSTREAM | Flags.SERIALIZED),\n    /**\n     * Custom out-of-band downstream event.\n     */\n    CUSTOM_DOWNSTREAM_OOB(290, Flags.DOWNSTREAM),\n    /**\n     * Custom sticky downstream event.\n     */\n    CUSTOM_DOWNSTREAM_STICKY(300, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY | Flags.STICKY_MULTI),\n    /**\n     * Custom upstream or downstream event. In-band when travelling downstream.\n     */\n    CUSTOM_BOTH(310, Flags.BOTH | Flags.SERIALIZED),\n    /**\n     * Custom upstream or downstream out-of-band event.\n     */\n    CUSTOM_BOTH_OOB(320, Flags.BOTH)\n    ;\n    \n    private static final int SHIFT = 8;\n    \n    private final int value;\n    \n    private EventType(int num, int flags) {\n        this.value = (num << SHIFT) | flags;\n    }\n    \n    @Override\n    public int intValue() {\n        return value;\n    }\n    \n    private static final class Flags {\n        public static final int UPSTREAM       = 1 << 0;\n        public static final int DOWNSTREAM     = 1 << 1;\n        public static final int SERIALIZED     = 1 << 2;\n        public static final int STICKY         = 1 << 3;\n        public static final int STICKY_MULTI   = 1 << 4;\n        public static final int BOTH = UPSTREAM | DOWNSTREAM;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/event/FlushStartEvent.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2008 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wim.taymans@chello.be>\n *                    2005 Wim Taymans <wim@fluendo.com>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.event;\n\nimport org.freedesktop.gstreamer.FlowReturn;\nimport org.freedesktop.gstreamer.Pad;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API;\n\n/**\n * Start a flush operation.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-flush-start\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-flush-start</a>\n * <p>\n * The flush start event can be sent upstream and downstream and travels\n * out-of-bounds with the dataflow.\n * <p>\n * It marks pads as being flushing and will make them return\n * {@link FlowReturn#FLUSHING} when used for data flow with {@link Pad#pushEvent},\n * {@link Pad#chain}, {@link Pad#getRange} and {@link Pad#pullRange}. Any event\n * (except a {@link FlushStopEvent}) received on a flushing pad will return\n * {@code false} immediately.\n * <p>\n * Elements should unlock any blocking functions and exit their streaming\n * functions as fast as possible when this event is received.\n * <p>\n * This event is typically generated after a seek to flush out all queued data\n * in the pipeline so that the new media is played as soon as possible.\n *\n */\npublic class FlushStartEvent extends Event {\n\n\n    /**\n     * This constructor is for internal use only.\n     *\n     * @param init initialization data.\n     */\n    FlushStartEvent(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Creates a new flush start event.\n     */\n    public FlushStartEvent() {\n        super(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_flush_start()));\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/event/FlushStopEvent.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2008 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wim.taymans@chello.be>\n *                    2005 Wim Taymans <wim@fluendo.com>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.event;\n\nimport org.freedesktop.gstreamer.glib.Natives;\nimport static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API;\n\n/**\n * Stop a flush operation.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-flush-stop\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-flush-stop</a>\n * <p>\n * The flush stop event can be sent upstream and downstream and travels\n * out-of-bounds with the dataflow. It is typically sent after sending a\n * {@link FlushStartEvent} event to make the pads accept data again.\n * <p>\n * Elements can process this event synchronized with the dataflow since the\n * preceeding FLUSH_START event stopped the dataflow.\n * <p>\n * This event is typically generated to complete a seek and to resume dataflow.\n */\npublic class FlushStopEvent extends Event {\n\n    /**\n     * This constructor is for internal use only.\n     *\n     * @param init initialization data.\n     */\n    FlushStopEvent(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Creates a new flush stop event.\n     */\n    public FlushStopEvent() {\n        super(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_flush_stop()));\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/event/LatencyEvent.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2008 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wim.taymans@chello.be>\n *                    2005 Wim Taymans <wim@fluendo.com>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.event;\n\nimport org.freedesktop.gstreamer.glib.Natives;\nimport static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API;\n\n/**\n * Notification of new latency adjustment.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-latency\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-latency</a>\n * <p>\n * The event is sent upstream from the sinks and notifies elements that they\n * should add an additional latency to the timestamps before synchronising\n * against the clock.\n * <p>\n * The latency is mostly used in live sinks and is always expressed in the time\n * format.\n */\npublic class LatencyEvent extends Event {\n\n    /**\n     * This constructor is for internal use only.\n     *\n     * @param init initialization data.\n     */\n    LatencyEvent(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Create a new latency event.\n     *\n     * @param latency the new latency value to add to timestamps.\n     */\n    public LatencyEvent(long latency) {\n        super(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_latency(latency)));\n    }\n\n    /**\n     * Gets the latency in the latency event.\n     *\n     * @return the latency.\n     */\n    public long getLatency() {\n        long[] latency = new long[1];\n        GSTEVENT_API.gst_event_parse_latency(this, latency);\n        return latency[0];\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/event/NavigationEvent.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2008 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wim.taymans@chello.be>\n *                    2005 Wim Taymans <wim@fluendo.com>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.event;\n\nimport org.freedesktop.gstreamer.Structure;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GType;\nimport static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API;\n\n/**\n * Navigation events are usually used for communicating user requests, such as\n * mouse or keyboard movements, to upstream elements.\n */\n// @TODO API seems OK but need to check and update against GstNavigation\npublic class NavigationEvent extends Event {\n\n    /**\n     * This constructor is for internal use only.\n     *\n     * @param init initialization data.\n     */\n    NavigationEvent(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Creates a new navigation event from the given description.\n     * <p>\n     * Unless you really need a custom navigation event, use one of the static\n     * convenience methods for creating navigation events.\n     *\n     * @param structure the description of the navigation event.\n     */\n    public NavigationEvent(Structure structure) {\n        this(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_navigation(structure)));\n    }\n\n    /**\n     * Gets a human-readable string representation of this navigation event.\n     *\n     * @return a string\n     */\n    @Override\n    public String toString() {\n        Structure s = getStructure();\n        String event = s.getString(\"event\");\n        if (event.startsWith(\"key-\")) {\n            return String.format(\"%s: [key=%s]\",\n                    event, s.getString(\"key\"));\n        } else if (event.startsWith(\"mouse-\")) {\n            return String.format(\"%s: [x=%f, y=%f button=%x]\",\n                    event,\n                    s.getDouble(\"pointer_x\"), s.getDouble(\"pointer_y\"),\n                    s.getInteger(\"button\"));\n        } else {\n            return String.format(\"%s\",\n                    s.getString(\"event\"));\n        }\n    }\n\n    /**\n     * Creates a mouse navigation event.\n     *\n     * @param event the type of mouse event.\n     * @param x the X location of the mouse cursor\n     * @param y the Y location of the mouse cursor\n     * @param button the button(s) currently pressed\n     * @return a new navigation event\n     */\n    public static NavigationEvent createMouseEvent(String event, double x, double y, int button) {\n        return new MouseEvent(event, x, y, button);\n    }\n\n    /**\n     * Creates a mouse move navigation event.\n     *\n     * @param x the X location of the mouse cursor\n     * @param y the Y location of the mouse cursor\n     * @param button the button(s) currently pressed\n     * @return a new navigation event\n     */\n    public static NavigationEvent createMouseMoveEvent(double x, double y, int button) {\n        return createMouseEvent(\"mouse-move\", x, y, button);\n    }\n\n    /**\n     * Creates a mouse button press navigation event.\n     *\n     * @param x the X location of the mouse cursor\n     * @param y the Y location of the mouse cursor\n     * @param button the button(s) currently pressed\n     * @return a new navigation event\n     */\n    public static NavigationEvent createMouseButtonPressEvent(double x, double y, int button) {\n        return createMouseEvent(\"mouse-button-press\", x, y, button);\n    }\n\n    /**\n     * Creates a mouse button release navigation event.\n     *\n     * @param x the X location of the mouse cursor\n     * @param y the Y location of the mouse cursor\n     * @param button the button(s) currently pressed\n     * @return a new navigation event\n     */\n    public static NavigationEvent createMouseButtonReleaseEvent(double x, double y, int button) {\n        return createMouseEvent(\"mouse-button-release\", x, y, button);\n    }\n\n    /**\n     * Creates a new key navigation event.\n     *\n     * @param event the type of key event.\n     * @param key the ascii key code for the key.\n     * @return a new navigation event\n     */\n    public static NavigationEvent createKeyEvent(String event, String key) {\n        return new KeyEvent(event, key);\n    }\n\n    /**\n     * Creates a new key press navigation event.\n     *\n     * @param key the ascii key code for the key.\n     * @return a new navigation event\n     */\n    public static NavigationEvent createKeyPressEvent(String key) {\n        return createKeyEvent(\"key-press\", key);\n    }\n\n    /**\n     * Creates a new key release navigation event.\n     *\n     * @param key the ascii key code for the key.\n     * @return a new navigation event\n     */\n    public static NavigationEvent createKeyReleaseEvent(String key) {\n        return createKeyEvent(\"key-release\", key);\n    }\n\n    private static final class MouseEvent extends NavigationEvent {\n\n        public MouseEvent(String event, double x, double y, int button) {\n            super(new Structure(\"application/x-gst-navigation\",\n                    \"event\", GType.STRING, event,\n                    \"button\", GType.INT, button,\n                    \"pointer_x\", GType.DOUBLE, x,\n                    \"pointer_y\", GType.DOUBLE, y));\n        }\n\n        /**\n         * Gets a human-readable string representation of this navigation event.\n         *\n         * @return a string\n         */\n        @Override\n        public String toString() {\n            Structure s = getStructure();\n            return String.format(\"%s: [x=%f, y=%f button=%x]\",\n                    s.getString(\"event\"),\n                    s.getDouble(\"pointer_x\"), s.getDouble(\"pointer_y\"),\n                    s.getInteger(\"button\"));\n        }\n    }\n\n    private static final class KeyEvent extends NavigationEvent {\n\n        public KeyEvent(String event, String key) {\n            super(new Structure(\"application/x-gst-navigation\",\n                    \"event\", GType.STRING, event,\n                    \"key\", GType.STRING, key));\n        }\n\n        /**\n         * Gets a human-readable string representation of this navigation event.\n         *\n         * @return a string\n         */\n        @Override\n        public String toString() {\n            Structure s = getStructure();\n            return String.format(\"%s: [key=%s]\",\n                    s.getString(\"event\"), s.getString(\"key\"));\n        }\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/event/QOSEvent.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2008 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wim.taymans@chello.be>\n *                    2005 Wim Taymans <wim@fluendo.com>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.event;\n\nimport org.freedesktop.gstreamer.glib.Natives;\nimport static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API;\n\n/**\n * A quality message. Used to indicate to upstream elements that the downstream\n * elements are being starved of or flooded with data.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-qos\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-qos</a>\n * <p>\n * <tt>proportion</tt> indicates the real-time performance of the streaming in\n * the element that generated the QoS event (usually the sink). The value is\n * generally computed based on more long term statistics about the streams\n * timestamps compared to the clock.\n * <p>\n * A value &lt; 1.0 indicates that the upstream element is producing data faster\n * than real-time. A value &gt; 1.0 indicates that the upstream element is not\n * producing data fast enough. 1.0 is the ideal <tt>proportion</tt> value. The\n * proportion value can safely be used to lower or increase the quality of the\n * element.\n * <p>\n * <tt>difference</tt> is the difference against the clock in running time of\n * the last buffer that caused the element to generate the QOS event. A negative\n * value means that the buffer with <tt>timestamp</tt> arrived in time. A\n * positive value indicates how late the buffer with <tt>timestamp</tt> was.\n * <p>\n * <tt>timestamp</tt> is the timestamp of the last buffer that cause the element\n * to generate the QOS event. It is expressed in running time and thus an ever\n * increasing value.\n * <p>\n * The upstream element can use the <tt>diff</tt> and <tt>timestamp</tt> values\n * to decide whether to process more buffers. For positive <tt>difference</tt>,\n * all buffers with timestamp <= <tt>timestamp</tt> + <tt>difference</tt> will\n * certainly arrive late in the sink as well.\n * <p>\n * The application can use general event probes to intercept the QoS event and\n * implement custom application specific QoS handling.\n *\n */\npublic class QOSEvent extends Event {\n\n    /**\n     * This constructor is for internal use only.\n     *\n     * @param init initialization data.\n     */\n    QOSEvent(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Creates a new quality-of-service event.\n     *\n     *\n     * @param proportion the proportion of the qos message\n     * @param difference the time difference of the last Clock sync\n     * @param timestamp the timestamp of the buffer\n     */\n    public QOSEvent(QOSType type, double proportion, long difference, long timestamp) {\n        super(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_qos(type, proportion, difference, timestamp)));\n    }\n\n    /**\n     * @return the proportion.\n     */\n    public QOSType getType() {\n        QOSType[] type = {null};\n        GSTEVENT_API.gst_event_parse_qos(this, type, null, null, (long[]) null);\n        return type[0];\n    }\n\n    /**\n     * Gets the proportion value of this event.\n     * <p>\n     * The proportion indicates the real-time performance of the streaming in\n     * the element that generated the QoS event (usually the sink). The value is\n     * generally computed based on more long term statistics about the streams\n     * timestamps compared to the clock.\n     *\n     * @return the proportion.\n     */\n    public double getProportion() {\n        double[] p = {0d};\n        GSTEVENT_API.gst_event_parse_qos(this, null, p, null, (long[]) null);\n        return p[0];\n    }\n\n    /**\n     * Gets the difference value of this event.\n     * <p>\n     * This is the difference against the clock in running time of the last\n     * buffer that caused the element to generate the QOS event. A negative\n     * value means that the buffer with <tt>timestamp</tt> arrived in time. A\n     * positive value indicates how late the buffer with <tt>timestamp</tt> was.\n     *\n     * @return the difference.\n     */\n    public long getDifference() {\n        long[] diff = {0};\n        GSTEVENT_API.gst_event_parse_qos(this, null, null, diff, (long[]) null);\n        return diff[0];\n    }\n\n    /**\n     * Gets the timestamp from this event.\n     * <p>\n     * This is the timestamp of the last buffer that caused the element to\n     * generate the QOS event. It is expressed in running time and thus an ever\n     * increasing value.\n     *\n     * @return the timestamp\n     */\n    public long getTimestamp() {\n        long[] timestamp = new long[1];\n        GSTEVENT_API.gst_event_parse_qos(this, null, null, null, timestamp);\n        return timestamp[0];\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/event/QOSType.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.event;\n\nimport org.freedesktop.gstreamer.glib.NativeEnum;\n\n/**\n * The different types of QoS events that can be given to the\n * gst_event_new_qos() method.\n */\npublic enum QOSType implements NativeEnum<QOSType> {\n    /**\n     * The QoS event type that is produced when downstream elements are\n     * producing data too quickly and the element can't keep up processing the\n     * data. Upstream should reduce their processing rate. This type is also\n     * used when buffers arrive early or in time.\n     */\n    OVERFLOW(0),\n    /**\n     * The QoS event type that is produced when downstream elements are\n     * producing data too slowly and need to speed up their processing rate.\n     */\n    UNDERFLOW(1),\n    /**\n     * The QoS event type that is produced when the application enabled\n     * throttling to limit the datarate.\n     */\n    THROTTLE(2);\n    \n    private final int value;\n    \n    private QOSType(int value) {\n        this.value = value;\n    }\n\n    @Override\n    public int intValue() {\n        return value;\n    }\n    \n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/event/ReconfigureEvent.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2016 Christophe Lafolet\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.event;\n\nimport org.freedesktop.gstreamer.glib.Natives;\nimport static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API;\n\n/**\n * A reconfigure event. The purpose of the reconfigure event is to travel\n * upstream and make elements renegotiate their caps or reconfigure their buffer\n * pools. This is useful when changing properties on elements or changing the\n * topology of the pipeline.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-reconfigure\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-reconfigure</a>\n * <p>\n */\npublic class ReconfigureEvent extends Event {\n\n    /**\n     * This constructor is for internal use only.\n     *\n     * @param init initialization data.\n     */\n    ReconfigureEvent(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Creates a new reconfigure event.\n     */\n    public ReconfigureEvent() {\n        super(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_reconfigure()));\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/event/SeekEvent.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2008 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wim.taymans@chello.be>\n *                    2005 Wim Taymans <wim@fluendo.com>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.event;\n\nimport java.util.EnumSet;\nimport org.freedesktop.gstreamer.Format;\nimport org.freedesktop.gstreamer.glib.NativeFlags;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API;\n\n/**\n * A request for a new playback position and rate.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-seek\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-seek</a>\n * <p>\n * The seek event configures playback of the pipeline between <tt>start</tt> to <tt>stop</tt>\n * at the speed given in <tt>rate</tt>, also called a playback segment.\n * <p>\n * The <tt>start</tt> and <tt>stop</tt> values are expressed in <tt>format</tt>.\n * <p>\n * A <tt>rate</tt> of 1.0 means normal playback rate, 2.0 means double speed.\n * Negative values means backwards playback. A value of 0.0 for the\n * rate is not allowed and should be accomplished instead by PAUSING the\n * pipeline.\n * <p>\n * A pipeline has a default playback segment configured with a start\n * position of 0, a stop position of -1 and a rate of 1.0. The currently\n * configured playback segment can be queried with #GST_QUERY_SEGMENT. \n * <p>\n * <tt>startType</tt> and <tt>stopType</tt> specify how to adjust the currently configured \n * start and stop fields in <tt>segment</tt>. Adjustments can be made relative or\n * absolute to the last configured values. A type of {@link SeekType#NONE} means\n * that the position should not be updated.\n * <p>\n * When the rate is positive and <tt>start</tt> has been updated, playback will start\n * from the newly configured start position. \n * <p>\n * For negative rates, playback will start from the newly configured <tt>stop<tt>\n * position (if any). If the stop position if updated, it must be different from\n * -1 for negative rates.\n * <p>\n * It is not possible to seek relative to the current playback position, to do\n * this, PAUSE the pipeline, query the current playback position with\n * {@link org.gstreamer.Pipeline#queryPosition getPosition} and update the playback segment \n * current position with a {@link SeekType#SET} to the desired position.\n */\npublic class SeekEvent extends Event {\n    \n    /**\n     * This constructor is for internal use only.\n     * @param init initialization data.\n     */\n    SeekEvent(Initializer init) {\n        super(init);\n    }\n    \n    /**\n     * Creates a new seek event.\n     * \n     * @param rate the new playback rate\n     * @param format the format of the seek values\n     * @param flags the optional seek flags\n     * @param startType the type and flags for the new start position\n     * @param start the value of the new start position\n     * @param stopType the type and flags for the new stop position\n     * @param stop the value of the new stop position\n     */\n    public SeekEvent(double rate, Format format, EnumSet<SeekFlags> flags, \n            SeekType startType, long start, SeekType stopType, long stop) {\n        super(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_seek(sanitizeRate(rate), format, \n                NativeFlags.toInt(flags), startType, start, stopType, stop)));\n    }\n    \n    private static double sanitizeRate(double rate) {\n        if (rate == 0d) {\n            throw new IllegalArgumentException(\"Cannot have rate == 0.0\");\n        }\n        return rate;\n    }\n    /**\n     * Gets the playback rate.\n     * \n     * A <tt>rate</tt> of 1.0 means normal playback rate, 2.0 means double speed.\n     * Negative values means backwards playback. A value of 0.0 for the\n     * rate is not allowed and should be accomplished instead by PAUSING the\n     * pipeline.\n     * \n     * @return the playback rate.\n     */\n    public double getRate() {\n        double[] rate = { 0d };\n        GSTEVENT_API.gst_event_parse_seek(this, rate, null, null, null, null, null, null);\n        return rate[0];\n    }\n    \n    /**\n     * Gets the {@link Format} of the start and stop seek values.\n     * \n     * @return the format.\n     */\n    public Format getFormat() {\n        Format[] format = new Format[1];\n        GSTEVENT_API.gst_event_parse_seek(this, null, format, null, null, null, null, null);\n        return format[0];\n    }\n    \n    /**\n     * Gets the {@link SeekFlags} of this seek event.\n     * \n     * @return the seek flags.\n     */\n    public EnumSet<SeekFlags> getFlags() {\n        int[] flags = { 0 };\n        GSTEVENT_API.gst_event_parse_seek(this, null, null, flags, null, null, null, null);\n        return NativeFlags.fromInt(SeekFlags.class, flags[0]);\n    }\n    \n    /**\n     * Gets the SeekType of the start value.\n     * \n     * @return the SeekType.\n     */\n    public SeekType getStartType() {\n        SeekType[] type = new SeekType[1];\n        GSTEVENT_API.gst_event_parse_seek(this, null, null, null, type, null, null, null);\n        return type[0];\n    }\n    \n    /**\n     * Gets the start of the seek segment.\n     * \n     * @return the start of the seek.\n     */\n    public long getStart() {\n        long[] value = { 0 };\n        GSTEVENT_API.gst_event_parse_seek(this, null, null, null, null, value, null, null);\n        return value[0];\n    }\n    \n    /**\n     * Gets the SeekType of the start value.\n     * \n     * @return the SeekType.\n     */\n    public SeekType getStopType() {\n        SeekType[] type = new SeekType[1];\n        GSTEVENT_API.gst_event_parse_seek(this, null, null, null, null, null, type, null);\n        return type[0];\n    }\n    \n    /**\n     * Gets the stop position of the seek.\n     * \n     * @return the stop position.\n     */\n    public long getStop() {\n        long[] value = { 0 };\n        GSTEVENT_API.gst_event_parse_seek(this, null, null, null, null, null, null, value);\n        return value[0];\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/event/SeekFlags.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.event;\n\nimport org.freedesktop.gstreamer.glib.NativeFlags;\n\n/**\n * Flags to be used with {@link Pipeline#seek seek} or\n * {@link org.freedesktop.gstreamer.event.SeekEvent#SeekEvent SeekEvent}\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#GstSeekFlags\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#GstSeekFlags</a>\n * <p>\n * All flags can be used together.\n * <p>\n * A non flushing seek might take some time to perform as the currently playing\n * data in the pipeline will not be cleared.\n * <p>\n * An accurate seek might be slower for formats that don't have any indexes or\n * timestamp markers in the stream. Specifying this flag might require a\n * complete scan of the file in those cases.\n * <p>\n * When performing a segment seek: after the playback of the segment completes,\n * no EOS will be emitted by the element that performed the seek, but a\n * {@link Bus.SEGMENT_DONE} message will be posted on the bus by the element.\n * When this message is posted, it is possible to send a new seek event to\n * continue playback. With this seek method it is possible to perform seamless\n * looping or simple linear editing.\n */\npublic enum SeekFlags implements NativeFlags<SeekFlags> {\n\n//    /**\n//     * No flag.\n//     */\n//    NONE(0),\n    /**\n     * Flush pipeline.\n     */\n    FLUSH(1 << 0),\n    /**\n     * Accurate position is requested, this might be considerably slower for\n     * some formats.\n     */\n    ACCURATE(1 << 1),\n    /**\n     * Seek to the nearest keyframe. This might be faster but less accurate.\n     */\n    KEY_UNIT(1 << 2),\n    /**\n     * Perform a segment seek.\n     */\n    SEGMENT(1 << 3),\n    /**\n     * when doing fast forward or fast reverse playback, allow elements to skip\n     * frames instead of generating all frames. (Since 1.6)\n     */\n    TRICKMODE(1 << 4),\n    /**\n     * go to a location before the requested position, if\n     * %GST_SEEK_FLAG_KEY_UNIT this means the keyframe at or before the\n     * requested position the one at or before the seek target.\n     */\n    SNAP_BEFORE(1 << 5),\n    /**\n     * go to a location after the requested position, if %GST_SEEK_FLAG_KEY_UNIT\n     * this means the keyframe at of after the requested position.\n     */\n    SNAP_AFTER(1 << 6),\n    //    /**\n    //     * go to a position near the requested position, if %GST_SEEK_FLAG_KEY_UNIT\n    //     * this means the keyframe closest to the requested position, if both\n    //     * keyframes are at an equal distance, behaves like\n    //     * %GST_SEEK_FLAG_SNAP_BEFORE.\n    //     */\n    //    public final static int SNAP_NEAREST = SNAP_BEFORE | SNAP_AFTER;\n    /**\n     * when doing fast forward or fast reverse playback, request that elements\n     * only decode keyframes and skip all other content, for formats that have\n     * keyframes.\n     */\n    TRICKMODE_KEY_UNITS(1 << 7),\n    /**\n     * when doing fast forward or fast reverse playback, request that audio\n     * decoder elements skip decoding and output only gap events or silence.\n     */\n    TRICKMODE_NO_AUDIO(1 << 8);\n\n    private final int value;\n\n    private SeekFlags(int value) {\n        this.value = value;\n    }\n\n    @Override\n    public int intValue() {\n        return value;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/event/SeekType.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.event;\n\nimport org.freedesktop.gstreamer.glib.NativeEnum;\n\n/**\n * The different types of seek events. \n * <p>\n * When constructing a seek event with\n * gst_event_new_seek(), a format, a seek method and optional flags are to\n * be provided. The seek event is then inserted into the graph with\n * gst_pad_send_event() or gst_element_send_event().\n */\npublic enum SeekType implements NativeEnum<SeekType>{\n    /** No change in position is required. */\n    NONE(0),\n    /** Absolute position is requested. */\n    SET(1),\n    /** Relative position to duration is requested. */\n    END(2);\n    \n    private final int value;\n    \n    private SeekType(int value) {\n        this.value = value;\n    }\n\n    @Override\n    public int intValue() {\n        return value;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/event/SegmentEvent.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2008 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wim.taymans@chello.be>\n *                    2005 Wim Taymans <wim@fluendo.com>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.event;\n\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.Segment;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GstSegmentStruct;\nimport static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API;\n\n/**\n *\n * An event for {@link Segment}\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-segment\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-segment</a>\n * <p>\n * The segment event marks the range of buffers to be processed. All data not\n * within the segment range is not to be processed. This can be used\n * intelligently by plugins to apply more efficient methods of skipping unneeded\n * data. The valid range is expressed with the start and stop values.\n * <p>\n * The time value of the segment is used in conjunction with the start value to\n * convert the buffer timestamps into the stream time. This is usually done in\n * sinks to report the current stream_time. time represents the stream_time of a\n * buffer carrying a timestamp of start . time cannot be -1.\n * <p>\n * start cannot be -1, stop can be -1. If there is a valid stop given, it must\n * be greater or equal the start , including when the indicated playback rate is\n * {@literal < 0}\n * <p>\n * The applied_rate value provides information about any rate adjustment that\n * has already been made to the timestamps and content on the buffers of the\n * stream. (rate * applied_rate ) should always equal the rate that has been\n * requested for playback. For example, if an element has an input segment with\n * intended playback rate of 2.0 and applied_rate of 1.0, it can adjust incoming\n * timestamps and buffer content by half and output a segment event with rate of\n * 1.0 and applied_rate of 2.0\n * <p>\n * After a segment event, the buffer stream time is calculated with:\n * <p>\n * time + (TIMESTAMP(buf) - start) * ABS (rate * applied_rate)\n */\n//@TODO needs work to parse segments\npublic class SegmentEvent extends Event {\n\n    /**\n     * This constructor is for internal use only.\n     *\n     * @param init initialization data.\n     */\n    SegmentEvent(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Allocates a new segment event with the given segment.\n     */\n    SegmentEvent(GstSegmentStruct segment) {\n        this(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_segment(segment)));\n    }\n\n    /**\n     * Gets the {@link Segment} stored in this event.\n     * <p>\n     * <b>Note:</b> The Segment is owned by the event, so it should only be\n     * accessed whilst holding a reference to this SegmentEvent.\n     *\n     * @return the Segment stored in this event.\n     */\n    GstAPI.GstSegmentStruct getSegment() {\n        Pointer[] segmentPointer = new Pointer[1];\n        GSTEVENT_API.gst_event_parse_segment(this, segmentPointer);\n        GstSegmentStruct result = new GstAPI.GstSegmentStruct(segmentPointer[0]);\n        result.read();\n        return result;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/event/StepEvent.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2010 DHoyt <david.g.hoyt@gmail.com>\n * Copyright (c) 2010 Levente Farkas\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.event;\n\nimport org.freedesktop.gstreamer.Format;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API;\n\n/**\n * StepEvent.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-step\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-step</a>\n * <p>\n * The purpose of the step event is to instruct a sink to skip amount (expressed\n * in format) of media. It can be used to implement stepping through the video\n * frame by frame or for doing fast trick modes. A rate of {@literal <= 0.0} is\n * not allowed, pause the pipeline or reverse the playback direction of the\n * pipeline to get the same effect.\n * <p>\n * The flush flag will clear any pending data in the pipeline before starting\n * the step operation.\n * <p>\n * The intermediate flag instructs the pipeline that this step operation is part\n * of a larger step operation.\n */\npublic class StepEvent extends Event {\n\n    /**\n     * This constructor is for internal use only.\n     *\n     * @param init initialization data.\n     */\n    StepEvent(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Creates a new StepEvent event.\n     *\n     * @param format the format of amount\n     * @param amount the amount of data to step\n     * @param rate the step rate\n     * @param flush flushing steps\n     * @param intermediate intermediate steps\n     */\n    public StepEvent(Format format, long amount, double rate, boolean flush, boolean intermediate) {\n        super(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_step(format, amount, rate, flush, intermediate)));\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/event/StreamStartEvent.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2016 Christophe Lafolet\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.event;\n\n\nimport org.freedesktop.gstreamer.glib.Natives;\nimport static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API;\n\n/**\n * Stream Start event.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-stream-start\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-stream-start</a>\n * <p>\n */\npublic class StreamStartEvent extends Event {\n\t\n    /**\n     * This constructor is for internal use only.\n     * @param init initialization data.\n     */\n    StreamStartEvent(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Creates a new EOS event.\n     * @param stream_id identifier for this stream\n     */\n    public StreamStartEvent(final String stream_id) {\n        super(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_stream_start(stream_id)));\n    }\n}"
  },
  {
    "path": "src/org/freedesktop/gstreamer/event/TagEvent.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2008 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wim.taymans@chello.be>\n *                    2005 Wim Taymans <wim@fluendo.com>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.event;\n\nimport org.freedesktop.gstreamer.TagList;\nimport org.freedesktop.gstreamer.lowlevel.ReferenceManager;\n\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.glib.NativeObject;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API;\n\n/**\n * A metadata tag event.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-tag\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-tag</a>\n * <p>\n * The scope of the taglist specifies if the taglist applies to the complete\n * medium or only to this specific stream. As the tag event is a sticky event,\n * elements should merge tags received from upstream with a given scope with\n * their own tags with the same scope and create a new tag event from it.\n */\npublic class TagEvent extends Event {\n\n    /**\n     * This constructor is for internal use only.\n     *\n     * @param init initialization data.\n     */\n    TagEvent(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Creates a new TagEvent.\n     * <p>\n     * <b>Note:</b> This constructor takes ownership of the TagList. Attempts to\n     * access the TagList after passing it to this constructor will throw an\n     * exception.\n     *\n     * @param taglist the taglist to transmit with the event.\n     */\n    public TagEvent(TagList taglist) {\n        this(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_tag(taglist)));\n    }\n\n    /**\n     * Gets the {@link TagList} stored in this event.\n     * <p>\n     * <b>Note:</b> The TagList is owned by the event, so it should only be\n     * accessed whilst holding a reference to this TagEvent.\n     *\n     * @return the TagList stored in this event.\n     */\n    public TagList getTagList() {\n        Pointer[] taglist = new Pointer[1];\n        GSTEVENT_API.gst_event_parse_tag(this, taglist);\n//        TagList tl = new TagList(taglistInitializer(taglist[0], false, false));\n        TagList tl = Natives.objectFor(taglist[0], TagList.class, false, false);\n        ReferenceManager.addKeepAliveReference(tl, this);\n        return tl;\n    }\n//    private static Initializer taglistInitializer(Pointer ptr, boolean needRef, boolean ownsHandle) {\n//        if (ptr == null) {\n//            throw new IllegalArgumentException(\"Invalid native pointer\");\n//        }\n//        return new Initializer(ptr, needRef, ownsHandle);\n//    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/glib/GCancellable.java",
    "content": "/* \n * Copyright (c) 2021 Neil C Smith\n * Copyright (c) 2016 Isaac Raño Jares\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.glib;\n\nimport static org.freedesktop.gstreamer.lowlevel.GioAPI.GIO_API;\n\npublic class GCancellable extends GObject{\n\n\tpublic static final String GTYPE_NAME = \"GCancellable\";\n\n\tpublic GCancellable() {\n\t\tthis(Natives.initializer(GIO_API.g_cancellable_new()));\n\t}\n\t\n\tprivate GCancellable(Initializer init) {\n\t\tsuper(init);\n\t}\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/glib/GDate.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2016 Christophe Lafolet\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.glib;\n\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI;\n\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.lowlevel.GPointer;\n\n/**\n * Wrapper to the GDate data structure.\n * \n * See upstream documentation at <a href=\"https://developer.gnome.org/glib/stable/glib-Date-and-Time-Functions.html\"\n * >https://developer.gnome.org/glib/stable/glib-Date-and-Time-Functions.html</a>\n */\npublic class GDate extends NativeObject {\n    \n    public static final String GTYPE_NAME = \"GDate\";\n\n    GDate(Initializer init) {\n        this(new Handle(init.ptr, init.ownsHandle));\n    }\n    \n    GDate(Handle handle) {\n        super(handle);\n    }\n\n    public int getDay() {\n        return GlibAPI.GLIB_API.g_date_get_day(getRawPointer());\n    }\n    \n    public int getMonth() {\n        return GlibAPI.GLIB_API.g_date_get_month(getRawPointer());\n    }\n    public int getYear() {\n        return GlibAPI.GLIB_API.g_date_get_year(getRawPointer());\n    }\n    \n    @Override\n    public String toString() {\n        return \"\" + getYear() + \"-\" + getMonth() + \"-\" + getDay();\n    }\n    \n    public static GDate createInstance(int day, int month, int year) {\n        Pointer ptr = GlibAPI.GLIB_API.g_date_new_dmy(day, month, year);\n        return new GDate(new Handle(new GPointer(ptr), true));\n    }\n    \n    public static GDate createInstance(int julian_day) {\n        Pointer ptr = GlibAPI.GLIB_API.g_date_new_julian(julian_day);\n        return new GDate(new Handle(new GPointer(ptr), true));\n    }\n    \n    private static final class Handle extends NativeObject.Handle {\n\n        public Handle(GPointer ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n\n        @Override\n        protected void disposeNativeHandle(GPointer ptr) {\n            GlibAPI.GLIB_API.g_date_free(ptr.getPointer());\n        }\n        \n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/glib/GError.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.glib;\n\nimport java.util.Objects;\n\n/**\n * Base GLib error type.\n */\npublic class GError {\n    \n    private final int code;\n    private final String message;\n    \n    /**\n     * Creates a new instance of GError\n     * \n     * @param code native int error code\n     * @param message error message text\n     */\n    public GError(int code, String message) {\n        this.code = code;\n        this.message = Objects.requireNonNull(message);\n    }\n    \n    /**\n     * Gets a numeric code representing this error.\n     * \n     * @return an integer code.\n     */\n    public final int getCode() {\n        return code;\n    }\n    /**\n     * Gets a string representation of this error.\n     *\n     * @return a string representing the error.\n     */\n    public String getMessage() {\n        return message;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/glib/GInetAddress.java",
    "content": "/* \n * Copyright (c) 2021 Neil C Smith\n * Copyright (c) 2016 Isaac Raño Jares\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.glib;\n\nimport static org.freedesktop.gstreamer.lowlevel.GioAPI.GIO_API;\n\npublic class GInetAddress extends GObject{\n\n\tpublic static final String GTYPE_NAME = \"GInetAddress\";\n\n\tGInetAddress(Initializer init) {\n\t\tsuper(init);\n\t}\n\n\tpublic String getAddress() {\n\t\treturn GIO_API.g_inet_address_to_string(getRawPointer());\n\t}\n\t\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/glib/GInetSocketAddress.java",
    "content": "/* \n * Copyright (c) 2021 Neil C Smith\n * Copyright (c) 2016 Isaac Raño Jares\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.glib;\n\nimport static org.freedesktop.gstreamer.lowlevel.GioAPI.GIO_API;\n\nimport com.sun.jna.Pointer;\n\npublic class GInetSocketAddress extends GSocketAddress {\n\n\tpublic static final String GTYPE_NAME = \"GInetSocketAddress\";\n\t\n\tpublic GInetSocketAddress(String address, int port)  {\n\t\tthis(createRawAddress(address, port));\n\t}\n\t\n\tGInetSocketAddress(Initializer init) {\n\t\tsuper(init);\n\t}\n        \n        public GInetAddress getAddress() {\n            return (GInetAddress) get(\"address\");\n        }\n\n\tpublic int getPort() {\n\t\treturn (Integer) get(\"port\");\n\t}\n        \n        private static Initializer createRawAddress(String address, int port) {\n            Pointer nativePointer = GIO_API.g_inet_socket_address_new_from_string(address, port);\n            if (nativePointer == null) {\n                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\");\n            }\n            return Natives.initializer(nativePointer);\n        }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/glib/GLib.java",
    "content": "/* \n * \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2018 Ingo Randalf\n *\n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.glib;\n\nimport java.util.stream.Stream;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI;\nimport static org.freedesktop.gstreamer.glib.Natives.registration;\n\n/**\n * Miscellaneous Utility Functions — a selection of portable utility functions from GLib\n * \n * Documentation derived from https://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html#g-setenv\n */\npublic class GLib {\n\n    /**\n     * Sets an environment variable. On UNIX, both the variable's name and value\n     * can be arbitrary byte strings, except that the variable's name cannot\n     * contain '='. On Windows, they should be in UTF-8.\n     *\n     * Note that on some systems, when variables are overwritten, the memory\n     * used for the previous variables and its value isn't reclaimed.\n     *\n     * You should be mindful of the fact that environment variable handling in\n     * UNIX is not thread-safe, and your program may crash if one thread calls\n     * g_setenv() while another thread is calling getenv(). (And note that many\n     * functions, such as gettext(), call getenv() internally.) This function is\n     * only safe to use at the very start of your program, before creating any\n     * other threads (or creating objects that create worker threads of their\n     * own).\n     * \n     * @param variable the environment variable to set, must not contain '='. \n     * @param value the value to set the variable to.\n     * @param overwrite whether to change the variable if it already exists.\n     * @return FALSE if the environment variable couldn't be set.\n     */\n    public static boolean setEnv(String variable, final String value, boolean overwrite) {\n        return GlibAPI.GLIB_API.g_setenv(variable, value, overwrite);\n    }\n\n    /**\n     * Returns the value of an environment variable.\n     *\n     * On UNIX, the name and value are byte strings which might or might not be\n     * in some consistent character set and encoding. On Windows, they are in\n     * UTF-8. On Windows, in case the environment variable's value contains\n     * references to other environment variables, they are expanded.\n     * \n     * @param variable the environment variable to get. \n     * @return the value of the environment variable, or NULL if the environment\n     * variable is not found.\n     */\n    public static String getEnv(String variable) {\n        return GlibAPI.GLIB_API.g_getenv(variable);\n    }\n\n    /**\n     * Removes an environment variable from the environment.\n     *\n     * Note that on some systems, when variables are overwritten, the memory\n     * used for the previous variables and its value isn't reclaimed.\n     *\n     * You should be mindful of the fact that environment variable handling in\n     * UNIX is not thread-safe, and your program may crash if one thread calls\n     * g_unsetenv() while another thread is calling getenv(). (And note that\n     * many functions, such as gettext(), call getenv() internally.) This\n     * function is only safe to use at the very start of your program, before\n     * creating any other threads (or creating objects that create worker\n     * threads of their own).\n     *\n     * @param variable the environment variable to remove, must not contain '='.\n     */\n    public static void unsetEnv(String variable) {\n        GlibAPI.GLIB_API.g_unsetenv(variable);\n    }\n    \n    public static class Types implements NativeObject.TypeProvider {\n\n        @Override\n        public Stream<NativeObject.TypeRegistration<?>> types() {\n            return Stream.of(\n                    registration(GDate.class, GDate.GTYPE_NAME, GDate::new),\n                    registration(GInetAddress.class, GInetAddress.GTYPE_NAME, GInetAddress::new),\n                    registration(GSocket.class, GSocket.GTYPE_NAME, GSocket::new),\n                    registration(GSocketAddress.class, GSocketAddress.GTYPE_NAME, GSocketAddress::new),\n                    registration(GInetSocketAddress.class, GInetSocketAddress.GTYPE_NAME, GInetSocketAddress::new)\n \n            );\n        }\n        \n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/glib/GLibException.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.glib;\n\n/**\n * Thrown when a gstreamer error occurs.\n */\npublic class GLibException extends RuntimeException {\n\n    /**\n     * Creates a new instance of <code>GLibException</code> without detail message.\n     */\n    public GLibException() {\n    }\n\n    /**\n     * Constructs an instance of <code>GLibException</code> with the specified detail message.\n     * \n     * @param msg the detail message.\n     */\n    public GLibException(String msg) {\n        super(msg);\n    }\n    public GLibException(GError error) {\n        super(error.getMessage());\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/glib/GMainContext.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.glib;\n\nimport org.freedesktop.gstreamer.lowlevel.*;\nimport com.sun.jna.Pointer;\nimport static org.freedesktop.gstreamer.lowlevel.GlibAPI.GLIB_API;\n\n/**\n *\n */\npublic class GMainContext extends RefCountedObject {\n    \n    public GMainContext() {\n        this(Natives.initializer(GLIB_API.g_main_context_new()));\n    }\n    private GMainContext(Initializer init) {\n        super(new Handle(init.ptr, init.ownsHandle), init.needRef);\n    }\n    \n    public int attach(GSource source) {\n        return GLIB_API.g_source_attach(source, this);\n    }\n    public static GMainContext getDefaultContext() {\n        return new GMainContext(Natives.initializer(GLIB_API.g_main_context_default(), false, false));\n    }\n    \n    private static final class Handle extends RefCountedObject.Handle {\n\n        public Handle(GPointer ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n\n        @Override\n        protected void disposeNativeHandle(GPointer ptr) {\n            GLIB_API.g_main_context_unref(ptr);\n        }\n\n        @Override\n        protected void ref() {\n            GLIB_API.g_main_context_ref(getPointer());\n        }\n\n        @Override\n        protected void unref() {\n            GLIB_API.g_main_context_unref(getPointer());\n        }\n        \n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/glib/GObject.java",
    "content": "/*\n * Copyright (c) 2020 Neil C Smith\n * Copyright (C) 2014 Tom Greenwood <tgreenwood@cafex.com>\n * Copyright (C) 2009 Levente Farkas\n * Copyright (C) 2009 Tamas Korodi <kotyo@zamba.fm>\n * Copyright (c) 2009 Andres Colubri\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.glib;\n\nimport static org.freedesktop.gstreamer.lowlevel.GObjectAPI.GOBJECT_API;\nimport static org.freedesktop.gstreamer.lowlevel.GSignalAPI.GSIGNAL_API;\nimport static org.freedesktop.gstreamer.lowlevel.GValueAPI.GVALUE_API;\n\nimport java.net.URI;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\nimport org.freedesktop.gstreamer.lowlevel.GObjectAPI;\nimport org.freedesktop.gstreamer.lowlevel.GObjectAPI.GParamSpec;\nimport org.freedesktop.gstreamer.lowlevel.GType;\nimport org.freedesktop.gstreamer.lowlevel.GValueAPI.GValue;\nimport org.freedesktop.gstreamer.lowlevel.GstTypes;\nimport org.freedesktop.gstreamer.lowlevel.IntPtr;\n\nimport com.sun.jna.Callback;\nimport com.sun.jna.CallbackThreadInitializer;\nimport com.sun.jna.Native;\nimport com.sun.jna.NativeLong;\nimport com.sun.jna.Pointer;\nimport com.sun.jna.ptr.IntByReference;\nimport com.sun.jna.ptr.PointerByReference;\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.Set;\nimport org.freedesktop.gstreamer.MiniObject;\nimport org.freedesktop.gstreamer.lowlevel.GObjectPtr;\nimport org.freedesktop.gstreamer.lowlevel.GPointer;\nimport org.freedesktop.gstreamer.lowlevel.GstMiniObjectPtr;\n\n/**\n * GObject is the fundamental type providing the common attributes and methods\n * for all object types in libraries based on the GObject system.\n * <p>\n * See upstream documentation at <a href=\"https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html\"\n * >https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html</a>\n *\n */\npublic abstract class GObject extends RefCountedObject {\n\n    private static final Level LIFECYCLE = Level.FINE;\n    private static final Logger LOG = Logger.getLogger(GObject.class.getName());\n    private static final CallbackThreadInitializer GCALLBACK_THREAD_INIT\n            = new CallbackThreadInitializer(true,\n                    Boolean.getBoolean(\"glib.detachCallbackThreads\"),\n                    \"GCallback\");\n    private static final Map<GObject, Boolean> STRONG_REFS\n            = new ConcurrentHashMap<GObject, Boolean>();\n    private static final GObjectAPI.GToggleNotify TOGGLE_NOTIFY = new ToggleNotify();\n\n    private final Handle handle;\n    private Map<Class<?>, Map<Object, GCallback>> callbackListeners;\n\n    protected GObject(Initializer init) {\n        this(new Handle(init.ptr.as(GObjectPtr.class, GObjectPtr::new), init.ownsHandle), init.needRef);\n    }\n\n    protected GObject(Handle handle, boolean needRef) {\n        super(handle);\n        this.handle = handle;\n        if (handle.ownsReference()) {\n            final boolean is_floating = GOBJECT_API.g_object_is_floating(handle.getPointer());\n            LOG.log(LIFECYCLE, () -> String.format(\n                    \"Initialising owned handle for %s floating = %b refs = %d need ref = %b\",\n                    this.getClass().getName(),\n                    is_floating,\n                    getRefCount(),\n                    needRef));\n\n            if (!needRef) {\n                if (is_floating) {\n                    // Sink floating ref\n                    handle.sink();\n                }\n            }\n\n            // If only one ref then this is weak!  This would only be the case where we didn't own\n            if (getRefCount() >= 1) {\n                STRONG_REFS.put(this, Boolean.TRUE);\n            }\n\n            GOBJECT_API.g_object_add_toggle_ref(handle.getPointer(), TOGGLE_NOTIFY, handle.objectID);\n            if (!needRef) {\n                // Toggle ref has created extra reference\n                handle.unref();\n            }\n        }\n    }\n\n    public <T> void connect(Class<T> listenerClass, T listener, Callback cb) {\n        String signal = listenerClass.getSimpleName().toLowerCase().replaceAll(\"_\", \"-\");\n        connect(signal, listenerClass, listener, cb);\n    }\n\n    public synchronized <T> void connect(String signal, Class<T> listenerClass, T listener, Callback cb) {\n        Native.setCallbackThreadInitializer(cb, GCALLBACK_THREAD_INIT);\n        addCallback(listenerClass, listener, new SignalCallback(signal, cb));\n    }\n\n    public synchronized <T> void disconnect(Class<T> listenerClass, T listener) {\n        removeCallback(listenerClass, listener);\n    }\n\n    public synchronized void emit(String signal, Object... arguments) {\n        GSIGNAL_API.g_signal_emit_by_name(this, signal, arguments);\n    }\n\n    public synchronized <T extends NativeObject> T emit(Class<T> resultType, String signal, Object... arguments) {\n        PointerByReference pointerToResult = new PointerByReference(null);\n        Object[] fullArguments = Arrays.copyOf(arguments, arguments.length + 1);\n        fullArguments[arguments.length] = pointerToResult;\n        emit(signal, fullArguments);\n        Pointer result = pointerToResult.getValue();\n        if (result == null) {\n            return null;\n        } else {\n            return Natives.objectFor(result, resultType, false, true);\n        }\n    }\n\n    /**\n     * Gets the current value of a <tt>GObject</tt> property.\n     *\n     * @param property The name of the property to get.\n     *\n     * @return A java value representing the <tt>GObject</tt> property value.\n     */\n    public Object get(String property) {\n        LOG.entering(\"GObject\", \"get\", new Object[]{property});\n        GObjectAPI.GParamSpec propertySpec = findProperty(property);\n        if (propertySpec == null) {\n            throw new IllegalArgumentException(\"Unknown property: \" + property);\n        }\n        final GType propType = propertySpec.value_type;\n        GValue propValue = new GValue();\n        GVALUE_API.g_value_init(propValue, propType);\n        GOBJECT_API.g_object_get_property(this, property, propValue);\n        if (propType.equals(GType.INT)) {\n            return GVALUE_API.g_value_get_int(propValue);\n        } else if (propType.equals(GType.UINT)) {\n            return GVALUE_API.g_value_get_uint(propValue);\n        } else if (propType.equals(GType.CHAR)) {\n            return Integer.valueOf(GVALUE_API.g_value_get_char(propValue));\n        } else if (propType.equals(GType.UCHAR)) {\n            return Integer.valueOf(GVALUE_API.g_value_get_uchar(propValue));\n        } else if (propType.equals(GType.LONG)) {\n            return GVALUE_API.g_value_get_long(propValue).longValue();\n        } else if (propType.equals(GType.ULONG)) {\n            return GVALUE_API.g_value_get_ulong(propValue).longValue();\n        } else if (propType.equals(GType.INT64)) {\n            return GVALUE_API.g_value_get_int64(propValue);\n        } else if (propType.equals(GType.UINT64)) {\n            return GVALUE_API.g_value_get_uint64(propValue);\n        } else if (propType.equals(GType.BOOLEAN)) {\n            return GVALUE_API.g_value_get_boolean(propValue);\n        } else if (propType.equals(GType.FLOAT)) {\n            return GVALUE_API.g_value_get_float(propValue);\n        } else if (propType.equals(GType.DOUBLE)) {\n            return GVALUE_API.g_value_get_double(propValue);\n        } else if (propType.equals(GType.STRING)) {\n            return GVALUE_API.g_value_get_string(propValue);\n        } else if (propType.equals(GType.OBJECT)) {\n            return GVALUE_API.g_value_dup_object(propValue);\n        } else if (GVALUE_API.g_value_type_transformable(propType, GType.OBJECT)) {\n            return GVALUE_API.g_value_dup_object(transform(propValue, GType.OBJECT));\n        } else if (GVALUE_API.g_value_type_transformable(propType, GType.INT)) {\n            return GVALUE_API.g_value_get_int(transform(propValue, GType.INT));\n        } else if (GVALUE_API.g_value_type_transformable(propType, GType.INT64)) {\n            return GVALUE_API.g_value_get_int64(transform(propValue, GType.INT64));\n        } else if (propValue.checkHolds(GType.BOXED)) {\n            // @TODO we already know the GType here - optimise this!\n            Class<? extends NativeObject> cls = GstTypes.classFor(propType);\n            if (cls != null) {\n                Pointer ptr = GVALUE_API.g_value_get_boxed(propValue);\n                return Natives.objectFor(ptr, cls, true, true);\n            }\n        }\n        throw new IllegalArgumentException(\"Unknown conversion from GType=\" + propType);\n    }\n\n    /**\n     * Gets the default value set to <tt>GObject</tt> property.\n     *\n     * @param property The name of the property.\n     * @return A java value representing the <tt>GObject</tt> property's default\n     * value.\n     */\n    public Object getPropertyDefaultValue(String property) {\n        GObjectAPI.GParamSpec propertySpec = findProperty(property);\n        if (propertySpec == null) {\n            throw new IllegalArgumentException(\"Unknown property: \" + property);\n        }\n        final GType propType = propertySpec.value_type;\n        return findProperty(property, propType).getDefault();\n    }\n\n    /**\n     * Gets the maximum value should be set to <tt>GObject</tt> property.\n     *\n     * @param property The name of the property.\n     * @return A java value representing the <tt>GObject</tt> property's maximum\n     * value.\n     */\n    public Object getPropertyMaximumValue(String property) {\n        GObjectAPI.GParamSpec propertySpec = findProperty(property);\n        if (propertySpec == null) {\n            throw new IllegalArgumentException(\"Unknown property: \" + property);\n        }\n        final GType propType = propertySpec.value_type;\n        return findProperty(property, propType).getMaximum();\n    }\n\n    /**\n     * Gets the minimum value should be set to <tt>GObject</tt> property.\n     *\n     * @param property The name of the property.\n     * @return A java value representing the <tt>GObject</tt> property's minimum\n     * value.\n     */\n    public Object getPropertyMinimumValue(String property) {\n        GObjectAPI.GParamSpec propertySpec = findProperty(property);\n        if (propertySpec == null) {\n            throw new IllegalArgumentException(\"Unknown property: \" + property);\n        }\n        final GType propType = propertySpec.value_type;\n        return findProperty(property, propType).getMinimum();\n    }\n\n    /**\n     * Get the reference count for an object. Should only really be used for\n     * debugging\n     *\n     * @return The reference count for the object\n     */\n    public int getRefCount() {\n        // Check if disposed as a disposed object may\n        // have been free'd and we mustn't access it's\n        // memory or we face possible SEGFAULT\n        GPointer ptr = handle.getPointer();\n\n        if (ptr != null) {\n//            final GObjectStruct struct = new GObjectStruct(this);\n//            return struct.ref_count;\n\n// ref count is after pointer to GTypeInstance\n            int count = ptr.getPointer().getInt(Native.POINTER_SIZE);\n            return count;\n        }\n        return 0;\n    }\n\n    /**\n     * Get the native GType type name.\n     * @return GType type name\n     */\n    public String getTypeName() {\n        return handle.getPointer().getGType().getTypeName();\n    }\n\n    public List<String> listPropertyNames() {\n        GObjectAPI.GParamSpec[] lst = listProperties();\n        List<String> result = new ArrayList<String>(lst.length);\n        for (int i = 0; i < lst.length; i++) {\n            result.add(lst[i].g_name);\n        }\n        return result;\n    }\n\n    /**\n     * Sets the value of a <tt>GObject</tt> property.\n     *\n     * @param property The property to set.\n     * @param data The value for the property. This must be of the type expected\n     * by gstreamer. As a convenience, NativeEnums will be converted to their\n     * int value.\n     */\n    public void set(String property, Object data) {\n        LOG.entering(\"GObject\", \"set\", new Object[]{property, data});\n        GObjectAPI.GParamSpec propertySpec = findProperty(property);\n        if (propertySpec == null /*|| data == null*/) {\n            throw new IllegalArgumentException(\"Unknown property: \" + property);\n        }\n        if (data instanceof NativeEnum) {\n            data = ((NativeEnum<?>) data).intValue();\n        }\n        final GType propType = propertySpec.value_type;\n\n        GValue propValue = new GValue();\n        GVALUE_API.g_value_init(propValue, propType);\n        if (propType.equals(GType.INT)) {\n            GVALUE_API.g_value_set_int(propValue, intValue(data));\n        } else if (propType.equals(GType.UINT)) {\n            GVALUE_API.g_value_set_uint(propValue, intValue(data));\n        } else if (propType.equals(GType.CHAR)) {\n            GVALUE_API.g_value_set_char(propValue, (byte) intValue(data));\n        } else if (propType.equals(GType.UCHAR)) {\n            GVALUE_API.g_value_set_uchar(propValue, (byte) intValue(data));\n        } else if (propType.equals(GType.LONG)) {\n            GVALUE_API.g_value_set_long(propValue, new NativeLong(longValue(data)));\n        } else if (propType.equals(GType.ULONG)) {\n            GVALUE_API.g_value_set_ulong(propValue, new NativeLong(longValue(data)));\n        } else if (propType.equals(GType.INT64)) {\n            GVALUE_API.g_value_set_int64(propValue, longValue(data));\n        } else if (propType.equals(GType.UINT64)) {\n            GVALUE_API.g_value_set_uint64(propValue, longValue(data));\n        } else if (propType.equals(GType.BOOLEAN)) {\n            GVALUE_API.g_value_set_boolean(propValue, booleanValue(data));\n        } else if (propType.equals(GType.FLOAT)) {\n            GVALUE_API.g_value_set_float(propValue, floatValue(data));\n        } else if (propType.equals(GType.DOUBLE)) {\n            GVALUE_API.g_value_set_double(propValue, doubleValue(data));\n        } else if (propType.equals(GType.STRING)) {\n            //\n            // Special conversion of java URI to gstreamer compatible uri\n            //\n            if (data instanceof URI) {\n                URI uri = (URI) data;\n                String uriString = uri.toString();\n                // Need to fixup file:/ to be file:/// for gstreamer\n                if (\"file\".equals(uri.getScheme()) && uri.getHost() == null) {\n                    final String path = uri.getRawPath();\n                    uriString = \"file://\" + path;\n                }\n                GVALUE_API.g_value_set_string(propValue, uriString);\n            } else if (data == null) {\n                GVALUE_API.g_value_set_string(propValue, null);\n            } else {\n                GVALUE_API.g_value_set_string(propValue, data.toString());\n            }\n        } else if (propType.equals(GType.OBJECT)) {\n            GVALUE_API.g_value_set_object(propValue, (GObject) data);\n        } else if (GVALUE_API.g_value_type_transformable(GType.INT64, propType)) {\n            transform(data, GType.INT64, propValue);\n        } else if (GVALUE_API.g_value_type_transformable(GType.LONG, propType)) {\n            transform(data, GType.LONG, propValue);\n        } else if (GVALUE_API.g_value_type_transformable(GType.INT, propType)) {\n            transform(data, GType.INT, propValue);\n        } else if (GVALUE_API.g_value_type_transformable(GType.DOUBLE, propType)) {\n            transform(data, GType.DOUBLE, propValue);\n        } else if (GVALUE_API.g_value_type_transformable(GType.FLOAT, propType)) {\n            transform(data, GType.FLOAT, propValue);\n        } else {\n            // Old behaviour\n            GOBJECT_API.g_object_set(this, property, data);\n            return;\n        }\n        GOBJECT_API.g_param_value_validate(propertySpec, propValue);\n        GOBJECT_API.g_object_set_property(this, property, propValue);\n        GVALUE_API.g_value_unset(propValue); // Release any memory\n    }\n\n    protected synchronized <T> void addCallback(Class<T> listenerClass, T listener, GCallback cb) {\n        final Map<Class<?>, Map<Object, GCallback>> signals = getCallbackMap();\n        Map<Object, GCallback> map = signals.get(listenerClass);\n        if (map == null) {\n            map = new HashMap<Object, GCallback>();\n            signals.put(listenerClass, map);\n        }\n        map.put(listener, cb);\n    }\n\n    @Override\n    public void dispose() {\n        super.dispose();\n        STRONG_REFS.remove(this);\n    }\n\n    @Override\n    public void invalidate() {\n        try {\n            // Need to increase the ref count before removing the toggle ref, so\n            // ensure the native object is not destroyed.\n            if (handle.ownsReference()) {\n                handle.ref();\n\n                // Disconnect the callback.\n                GOBJECT_API.g_object_remove_toggle_ref(handle.getPointer(), TOGGLE_NOTIFY, handle.objectID);\n            }\n            STRONG_REFS.remove(this);\n        } finally {\n            super.invalidate();\n        }\n    }\n\n    protected synchronized <T> void removeCallback(Class<T> listenerClass, T listener) {\n        final Map<Class<?>, Map<Object, GCallback>> signals = getCallbackMap();\n        Map<Object, GCallback> map = signals.get(listenerClass);\n        if (map != null) {\n            GCallback cb = map.remove(listener);\n            if (cb != null) {\n                cb.remove();\n            }\n            if (map.isEmpty()) {\n                signals.remove(listenerClass);\n                if (callbackListeners.isEmpty()) {\n                    callbackListeners = null;\n                }\n            }\n        }\n    }\n\n    //    public static <T extends GObject> T objectFor(Pointer ptr, Class<T> defaultClass) {\n//        return objectFor(ptr, defaultClass, true);\n//    }\n    private GObjectAPI.GParamSpec findProperty(String propertyName) {\n        Pointer ptr = GOBJECT_API.g_object_class_find_property(getRawPointer().getPointer(0), propertyName);\n        if (ptr == null) {\n            return null;\n        }\n        return new GObjectAPI.GParamSpec(ptr);\n    }\n\n    private GObjectAPI.GParamSpecTypeSpecific findProperty(String propertyName, GType type) {\n        Pointer ptr = GOBJECT_API.g_object_class_find_property(getRawPointer().getPointer(0), propertyName);\n        if (type.equals(GType.INT)) {\n            return new GObjectAPI.GParamSpecInt(ptr);\n        } else if (type.equals(GType.UINT)) {\n            return new GObjectAPI.GParamSpecUInt(ptr);\n        } else if (type.equals(GType.CHAR)) {\n            return new GObjectAPI.GParamSpecChar(ptr);\n        } else if (type.equals(GType.UCHAR)) {\n            return new GObjectAPI.GParamSpecUChar(ptr);\n        } else if (type.equals(GType.BOOLEAN)) {\n            return new GObjectAPI.GParamSpecBoolean(ptr);\n        } else if (type.equals(GType.LONG)) {\n            return new GObjectAPI.GParamSpecLong(ptr);\n        } else if (type.equals(GType.ULONG)) {\n            return new GObjectAPI.GParamSpecLong(ptr);\n        } else if (type.equals(GType.INT64)) {\n            return new GObjectAPI.GParamSpecInt64(ptr);\n        } else if (type.equals(GType.UINT64)) {\n            return new GObjectAPI.GParamSpecInt64(ptr);\n        } else if (type.equals(GType.FLOAT)) {\n            return new GObjectAPI.GParamSpecFloat(ptr);\n        } else if (type.equals(GType.DOUBLE)) {\n            return new GObjectAPI.GParamSpecDouble(ptr);\n        } else if (type.equals(GType.STRING)) {\n            return new GObjectAPI.GParamSpecString(ptr);\n        }\n        throw new IllegalArgumentException(\"Unknown conversion from GType=\" + type);\n    }\n\n    private synchronized final Map<Class<?>, Map<Object, GCallback>> getCallbackMap() {\n        if (callbackListeners == null) {\n            callbackListeners = new ConcurrentHashMap<Class<?>, Map<Object, GCallback>>();\n        }\n        return callbackListeners;\n    }\n\n    private GObjectAPI.GParamSpec[] listProperties() {\n        IntByReference len = new IntByReference();\n        Pointer ptrs = GOBJECT_API.g_object_class_list_properties(getRawPointer().getPointer(0), len);\n        if (ptrs == null) {\n            return null;\n        }\n\n        GParamSpec[] props = new GParamSpec[len.getValue()];\n        int offset = 0;\n        for (int i = 0; i < len.getValue(); i++) {\n            props[i] = new GObjectAPI.GParamSpec(ptrs.getPointer(offset));\n            offset += Native.POINTER_SIZE;\n        }\n        return props;\n    }\n\n    private static boolean booleanValue(Object value) {\n        if (value instanceof Boolean) {\n            return ((Boolean) value).booleanValue();\n        } else if (value instanceof Number) {\n            return ((Number) value).intValue() != 0;\n        } else if (value instanceof String) {\n            return Boolean.parseBoolean((String) value);\n        }\n        throw new IllegalArgumentException(\"Expected boolean value, not \" + value.getClass());\n    }\n\n    private static double doubleValue(Object value) {\n        if (value instanceof Number) {\n            return ((Number) value).doubleValue();\n        } else if (value instanceof String) {\n            return Double.parseDouble((String) value);\n        }\n        throw new IllegalArgumentException(\"Expected double value, not \" + value.getClass());\n    }\n\n    private static float floatValue(Object value) {\n        if (value instanceof Number) {\n            return ((Number) value).floatValue();\n        } else if (value instanceof String) {\n            return Float.parseFloat((String) value);\n        }\n        throw new IllegalArgumentException(\"Expected float value, not \" + value.getClass());\n    }\n\n    private static int intValue(Object value) {\n        if (value instanceof Number) {\n            return ((Number) value).intValue();\n        } else if (value instanceof String) {\n            return Integer.parseInt((String) value);\n        }\n        throw new IllegalArgumentException(\"Expected integer value, not \" + value.getClass());\n    }\n\n    private static long longValue(Object value) {\n        if (value instanceof Number) {\n            return ((Number) value).longValue();\n        } else if (value instanceof String) {\n            return Long.parseLong((String) value);\n        }\n        throw new IllegalArgumentException(\"Expected long value, not \" + value.getClass());\n    }\n\n    private static boolean setGValue(GValue value, GType type, Object data) {\n        if (type.equals(GType.INT)) {\n            GVALUE_API.g_value_set_int(value, intValue(data));\n        } else if (type.equals(GType.UINT)) {\n            GVALUE_API.g_value_set_uint(value, intValue(data));\n        } else if (type.equals(GType.CHAR)) {\n            GVALUE_API.g_value_set_char(value, (byte) intValue(data));\n        } else if (type.equals(GType.UCHAR)) {\n            GVALUE_API.g_value_set_uchar(value, (byte) intValue(data));\n        } else if (type.equals(GType.LONG)) {\n            GVALUE_API.g_value_set_long(value, new NativeLong(longValue(data)));\n        } else if (type.equals(GType.ULONG)) {\n            GVALUE_API.g_value_set_ulong(value, new NativeLong(longValue(data)));\n        } else if (type.equals(GType.INT64)) {\n            GVALUE_API.g_value_set_int64(value, longValue(data));\n        } else if (type.equals(GType.UINT64)) {\n            GVALUE_API.g_value_set_uint64(value, longValue(data));\n        } else if (type.equals(GType.BOOLEAN)) {\n            GVALUE_API.g_value_set_boolean(value, booleanValue(data));\n        } else if (type.equals(GType.FLOAT)) {\n            GVALUE_API.g_value_set_float(value, floatValue(data));\n        } else if (type.equals(GType.DOUBLE)) {\n            GVALUE_API.g_value_set_double(value, doubleValue(data));\n        } else {\n            return false;\n        }\n        return true;\n    }\n\n    private static GValue transform(GValue src, GType dstType) {\n        GValue dst = new GValue();\n        GVALUE_API.g_value_init(dst, dstType);\n        GVALUE_API.g_value_transform(src, dst);\n        return dst;\n    }\n\n    private static void transform(Object data, GType type, GValue dst) {\n        GValue src = new GValue();\n        GVALUE_API.g_value_init(src, type);\n        setGValue(src, type, data);\n        GVALUE_API.g_value_transform(src, dst);\n    }\n\n    protected abstract class GCallback {\n\n        protected final Callback cb;\n        protected final NativeLong id;\n        volatile boolean connected = false;\n\n        protected GCallback(NativeLong id, Callback cb) {\n            this.id = id != null ? id : new NativeLong(0);\n            this.cb = cb;\n            this.connected = this.id.longValue() != 0;\n        }\n\n        void remove() {\n            if (connected) {\n                disconnect();\n                connected = false;\n            }\n        }\n\n        abstract protected void disconnect();\n\n    }\n\n    /**\n     * Base interface for classes that implement a GInterface\n     */\n    public static interface GInterface {\n\n        /**\n         * Get the GObject implementing this interface.\n         *\n         * @return implementing GObject\n         */\n        public GObject getGObject();\n\n    }\n\n    private final class SignalCallback extends GCallback {\n\n        protected SignalCallback(String signal, Callback cb) {\n            super(handle.connectSignal(signal, cb), cb);\n            if (!connected) {\n                throw new IllegalArgumentException(String.format(\"Failed to connect signal '%s'\", signal));\n            }\n        }\n\n        @Override\n        synchronized protected void disconnect() {\n            handle.disconnectSignal(id);\n        }\n    }\n\n    protected static class Handle extends RefCountedObject.Handle {\n\n        private final IntPtr objectID;\n        private final Set<NativeLong> signals;\n\n        public Handle(GObjectPtr ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n            this.objectID = new IntPtr(System.identityHashCode(this));\n            signals = new HashSet<>();\n        }\n\n        private synchronized NativeLong connectSignal(String signal, Callback cb) {\n            NativeLong id = GOBJECT_API.g_signal_connect_data(getPointer(), signal, cb, null, null, 0);\n            if (id.longValue() != 0) {\n                signals.add(id);\n            }\n            return id;\n        }\n\n        private synchronized void disconnectSignal(NativeLong id) {\n            if (signals.remove(id)) {\n                GOBJECT_API.g_signal_handler_disconnect(getPointer(), id);\n            }\n        }\n\n        private synchronized void clearSignals() {\n            signals.forEach(id -> GOBJECT_API.g_signal_handler_disconnect(getPointer(), id));\n            signals.clear();\n        }\n\n        @Override\n        public void invalidate() {\n            clearSignals();\n            super.dispose();\n        }\n\n        @Override\n        public void dispose() {\n            clearSignals();\n            super.dispose();\n        }\n\n        @Override\n        protected void disposeNativeHandle(GPointer ptr) {\n            GOBJECT_API.g_object_remove_toggle_ref((GObjectPtr) ptr, TOGGLE_NOTIFY, objectID);\n        }\n\n        @Override\n        protected void ref() {\n            GOBJECT_API.g_object_ref(getPointer());\n        }\n\n        /**\n         * Sink floating reference. This will turn a floating reference into a\n         * real one.\n         */\n        protected void sink() {\n            GOBJECT_API.g_object_ref_sink(getPointer());\n        }\n\n        @Override\n        protected void unref() {\n            GOBJECT_API.g_object_unref(getPointer());\n        }\n\n        @Override\n        protected GObjectPtr getPointer() {\n            return (GObjectPtr) super.getPointer();\n        }\n\n        @Override\n        public String toString() {\n            GObjectPtr ptr = getPointer();\n            if (ptr != null) {\n                return ptr.getGType().getTypeName() + \" : \" + objectID;\n            } else {\n                return \"Disposed handle\";\n            }\n        }\n\n    }\n\n    private static final class ToggleNotify implements GObjectAPI.GToggleNotify {\n\n        @Override\n        public void callback(Pointer data, Pointer ptr, boolean is_last_ref) {\n\n            /*\n            * Manage the strong reference to this instance.  When this is the last\n            * reference to the underlying object, remove the strong reference so\n            * it can be garbage collected.  If it is owned by someone else, then make\n            * it a strong ref, so the java GObject for the underlying C object can\n            * be retained for later retrieval\n             */\n            GObject o = (GObject) NativeObject.instanceFor(ptr);\n            if (o == null) {\n                return;\n            }\n            LOG.log(LIFECYCLE, \"toggle_ref \" + o.getClass().getSimpleName()\n                    + \" (\" + ptr + \")\" + \" last_ref=\" + is_last_ref);\n            if (is_last_ref) {\n                STRONG_REFS.remove(o);\n            } else {\n                STRONG_REFS.put(o, Boolean.TRUE);\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/glib/GQuark.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2016 Christophe Lafolet\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.glib;\n\nimport org.freedesktop.gstreamer.lowlevel.GObjectAPI;\n\n/**\n * Quarks — a 2-way association between a string and a unique integer identifier.\n * \n * See upstream documentation at <a href=\"https://developer.gnome.org/glib/stable/glib-Quarks.html\"\n * >https://developer.gnome.org/glib/stable/glib-Quarks.html</a>\n * \n */\npublic class GQuark {\n    \n    private final int value;\n    \n    public GQuark(int value) {\n        this.value = value;\n    }\n    \n    public int intValue() {\n        return value;\n    }\n    \n    @Override\n    public String toString() {\n        return GObjectAPI.GOBJECT_API.g_quark_to_string(this);\n    }\n    \n    public static GQuark valueOf(String quark) {\n        return GObjectAPI.GOBJECT_API.g_quark_from_string(quark);\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/glib/GSocket.java",
    "content": "/* \n * Copyright (c) 2025 Neil C Smith\n * Copyright (c) 2016 Isaac Raño Jares\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.glib;\n\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GErrorStruct;\n\nimport static org.freedesktop.gstreamer.lowlevel.GioAPI.GIO_API;\nimport static org.freedesktop.gstreamer.lowlevel.GlibAPI.GLIB_API;\n\npublic class GSocket extends GObject {\n\n    public static final String GTYPE_NAME = \"GSocket\";\n\n    public GSocket(GSocketFamily family, GSocketType type, GSocketProtocol protocol) throws GLibException {\n        this(makeRawSocket(family, type, protocol));\n    }\n\n    GSocket(Initializer init) {\n        super(init);\n    }\n\n    public GSocket bind(String address, int port) {\n        GInetSocketAddress boundAddress = new GInetSocketAddress(address, port);\n        GErrorStruct reference = new GErrorStruct();\n        GErrorStruct[] errorArray = (GErrorStruct[]) reference.toArray(1);\n        if (!GIO_API.g_socket_bind(getRawPointer(),\n                Natives.getRawPointer(boundAddress),\n                true,\n                reference.getPointer())) {\n            throw new GLibException(extractAndClearError(errorArray[0]));\n        }\n        return this;\n    }\n\n    public void connect(String address, int port) {\n        GInetSocketAddress connectedAddress = new GInetSocketAddress(address, port);\n        GErrorStruct reference = new GErrorStruct();\n        GErrorStruct[] errorArray = (GErrorStruct[]) reference.toArray(1);\n        if (!GIO_API.g_socket_connect(getRawPointer(),\n                Natives.getRawPointer(connectedAddress),\n                Natives.getRawPointer(new GCancellable()),\n                reference.getPointer())) {\n            throw new GLibException(extractAndClearError(errorArray[0]));\n        }\n    }\n\n    public int getFD() {\n        return (Integer) get(\"fd\");\n    }\n\n    public GInetSocketAddress getLocalAddress() {\n        return (GInetSocketAddress) get(\"local-address\");\n    }\n\n    public GInetSocketAddress getRemoteAddress() {\n        return (GInetSocketAddress) get(\"remote-address\");\n    }\n\n    public GSocketFamily getSocketFamily() {\n        return GSocketFamily.fromGioValue((Integer) get(\"family\"));\n    }\n\n    public GSocketProtocol getSocketProtocol() {\n        return GSocketProtocol.fromGioValue((Integer) get(\"protocol\"));\n    }\n\n    public GSocketType getSocketType() {\n        return GSocketType.fromGioValue((Integer) get(\"type\"));\n    }\n\n    public boolean isBlocking() {\n        return (Boolean) get(\"blocking\");\n    }\n\n    private static String extractAndClearError(GErrorStruct struct) {\n        struct.read();\n        String err = struct.getMessage();\n        GLIB_API.g_error_free(struct.getPointer());\n        return err;\n    }\n\n    private static Initializer makeRawSocket(GSocketFamily family, GSocketType type, GSocketProtocol protocol) throws GLibException {\n        GErrorStruct reference = new GErrorStruct();\n        GErrorStruct[] errorArray = (GErrorStruct[]) reference.toArray(1);\n        Pointer socketPointer = GIO_API.g_socket_new(family.toGioValue(), type.toGioValue(), protocol.toGioValue(), reference.getPointer());\n        if (socketPointer == null) {\n            throw new GLibException(extractAndClearError(errorArray[0]));\n        }\n        return Natives.initializer(socketPointer);\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/glib/GSocketAddress.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2016 Isaac Raño Jares\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.glib;\n\npublic class GSocketAddress extends GObject{\n\n\tpublic static final String GTYPE_NAME = \"GSocketAddress\";\n\n\tpublic GSocketAddress(Initializer init) {\n\t\tsuper(init);\n\t}\n\n\tpublic GSocketFamily getFamily() {\n\t\treturn GSocketFamily.fromGioValue((Integer) get(\"family\"));\n\t}\n\n\t\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/glib/GSocketFamily.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2016 Isaac Raño Jares\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n\npackage org.freedesktop.gstreamer.glib;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI;\n\npublic enum GSocketFamily {\n\t\n\tINVALID\t(0x00),\n\tUNIX\t\t(GlibAPI.GLIB_SYSDEF_AF_UNIX),\n\tIPV4\t\t(GlibAPI.GLIB_SYSDEF_AF_INET),\n\tIPV6\t\t(GlibAPI.GLIB_SYSDEF_AF_INET6);\n\n\tprivate static final Map<Integer,GSocketFamily> fastResolveMap = new HashMap<Integer,GSocketFamily>();\n\tstatic {\n\t\tfor(GSocketFamily dataUnitType : values()) {\n\t\t\tfastResolveMap.put(dataUnitType.toGioValue(), dataUnitType);\n\t\t}\n\t}\n\n\tprivate int gioValue;\n\n\tprivate GSocketFamily(int gioValue) {\n\t\tthis.gioValue = gioValue;\n\t}\n\n\tpublic int toGioValue() {\n\t\treturn gioValue;\n\t}\n        \n        public static GSocketFamily fromGioValue(int gioValue) {\n            return fastResolveMap.get(gioValue);\n        }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/glib/GSocketProtocol.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2016 Isaac Raño Jares\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n\npackage org.freedesktop.gstreamer.glib;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic enum GSocketProtocol {\n\tUNKNOWN (-1),\n\tDEFAULT (0),\n\tTCP     (6),\n\tUDP     (17),\n\tSCTP \t(132);\n\n\tprivate static final Map<Integer,GSocketProtocol> fastResolveMap = new HashMap<Integer,GSocketProtocol>();\n\tstatic {\n\t\tfor(GSocketProtocol dataUnitType : values()) {\n\t\t\tfastResolveMap.put(dataUnitType.toGioValue(), dataUnitType);\n\t\t}\n\t}\n\n\tprivate int gioValue;\n\n\tprivate GSocketProtocol(int gioValue) {\n\t\tthis.gioValue = gioValue;\n\t}\n\n\tpublic int toGioValue() {\n\t\treturn gioValue;\n\t}\n        \n        public static GSocketProtocol fromGioValue(int gioValue) {\n            return fastResolveMap.get(gioValue);\n        }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/glib/GSocketType.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2016 Isaac Raño Jares\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n\npackage org.freedesktop.gstreamer.glib;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic enum GSocketType {\n\tINVALID\t\t(0),\n\tSTREAM\t\t(1),\n\tDATAGRAM\t(2),\n\tSEQPACKET\t(3);\n\n\tprivate static final Map<Integer,GSocketType> fastResolveMap = new HashMap<Integer,GSocketType>();\n\tstatic {\n\t\tfor(GSocketType dataUnitType : values()) {\n\t\t\tfastResolveMap.put(dataUnitType.toGioValue(), dataUnitType);\n\t\t}\n\t}\n\n\tprivate int gioValue;\n\n\tprivate GSocketType(int gioValue) {\n\t\tthis.gioValue = gioValue;\n\t}\n\n\tpublic int toGioValue() {\n\t\treturn gioValue;\n\t}\n        \n        public static GSocketType fromGioValue(int gioValue) {\n            return fastResolveMap.get(gioValue);\n        }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/glib/GSource.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.glib;\n\nimport org.freedesktop.gstreamer.lowlevel.*;\nimport static org.freedesktop.gstreamer.lowlevel.GlibAPI.GLIB_API;\n\nimport java.util.concurrent.Callable;\n\nimport com.sun.jna.Pointer;\n/**\n *\n */\npublic class GSource extends RefCountedObject {\n    \n    GSource(Initializer init) {\n        super(new Handle(init.ptr, init.ownsHandle), init.needRef);\n    }\n    \n    public int attach(GMainContext context) {\n        return GLIB_API.g_source_attach(this, context);\n    }\n    \n    public void setCallback(final Callable<Boolean> call) {\n        this.callback = new GlibAPI.GSourceFunc() {\n            public boolean callback(Pointer data) {\n                if (GLIB_API.g_source_is_destroyed(getRawPointer())) {\n                    return false;\n                }\n                try {\n                    return call.call().booleanValue();\n                } catch (Exception ex) {\n                    return false;\n                }\n            }\n        };\n        GLIB_API.g_source_set_callback(this, callback, null, null);\n    }\n    \n    private GlibAPI.GSourceFunc callback;\n    \n    private static final class Handle extends RefCountedObject.Handle {\n\n        Handle(GPointer ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n\n        @Override\n        protected void disposeNativeHandle(GPointer ptr) {\n            GLIB_API.g_source_destroy(ptr.getPointer());\n            GLIB_API.g_source_unref(ptr.getPointer());\n        }\n\n        @Override\n        protected void ref() {\n            GLIB_API.g_source_ref(getPointer().getPointer());\n        }\n\n        @Override\n        protected void unref() {\n            GLIB_API.g_source_unref(getPointer().getPointer());\n        }\n        \n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/glib/MainContextExecutorService.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.glib;\n\nimport static org.freedesktop.gstreamer.lowlevel.GlibAPI.GLIB_API;\n\nimport java.util.ArrayList;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.concurrent.AbstractExecutorService;\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.Delayed;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.FutureTask;\nimport java.util.concurrent.ScheduledExecutorService;\nimport java.util.concurrent.ScheduledFuture;\nimport java.util.concurrent.TimeUnit;\n\n/**\n * Wraps the glib main loop/main context in a ScheduledExecutor interface.\n */\npublic class MainContextExecutorService extends AbstractExecutorService implements ScheduledExecutorService {\n    private final List<Runnable> bgTasks = new LinkedList<Runnable>();\n    private final GMainContext context;\n    private final Callable<Boolean> idleCallback = new Callable<Boolean>() {\n\n        public Boolean call() throws Exception {\n            //            System.out.println(\"Running g_idle callbacks\");\n            List<Runnable> tasks = new ArrayList<Runnable>();\n            synchronized (bgTasks) {\n                tasks.addAll(bgTasks);\n                bgTasks.clear();\n            }\n            for (Runnable r : tasks) {\n                r.run();\n            }\n            return false;\n        }\n    };\n    private GSource idleSource = null;\n    private volatile boolean running = true;\n    \n    public MainContextExecutorService(GMainContext context) {\n        this.context = context;\n    }\n    public boolean awaitTermination(long timeout, TimeUnit units) throws InterruptedException {\n        throw new UnsupportedOperationException(\"Not supported yet.\");\n    }\n    public void execute(Runnable runnable) {\n        invokeLater(runnable);\n    }\n\n\n    public boolean isShutdown() {\n        return !running;\n    }\n\n    public boolean isTerminated() {\n        synchronized (bgTasks) {\n            return !isShutdown() && bgTasks.isEmpty();\n        }\n    }\n\n    public ScheduledFuture<?> schedule(Runnable runnable, long delay, TimeUnit units) {\n        return new ScheduledTimeout<Object>(Executors.callable(runnable), delay, units);\n    }\n\n    public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit units) {\n        return new ScheduledTimeout<V>(callable, delay, units);\n    }\n\n    public ScheduledFuture<?> scheduleAtFixedRate(Runnable runnable, long initialiDelay, long period, TimeUnit units) {\n        return new ScheduledTimeout<Object>(Executors.callable(runnable), initialiDelay, period, units);\n    }\n\n    public ScheduledFuture<?> scheduleWithFixedDelay(Runnable runnable, long initialiDelay, long delay, TimeUnit units) {\n        return new ScheduledTimeout<Object>(Executors.callable(runnable), initialiDelay, delay, units);\n    }\n    public void shutdown() {\n        shutdownNow();\n    }\n    public List<Runnable> shutdownNow() {\n        List<Runnable> tasks = new ArrayList<Runnable>();\n        synchronized (bgTasks) {\n            tasks.addAll(bgTasks);\n            bgTasks.clear();\n        }\n        return tasks;\n    }\n    private void invokeLater(final Runnable r) {\n        //        System.out.println(\"Scheduling idle callbacks\");\n        synchronized (bgTasks) {\n            boolean empty = bgTasks.isEmpty();\n            bgTasks.add(r);\n            // Only trigger the callback if there were no existing elements in the list\n            // otherwise it is already triggered\n            if (empty) {\n                idleSource = GLIB_API.g_idle_source_new();\n                idleSource.setCallback(idleCallback);\n                idleSource.attach(context);\n            }\n        }\n    }\n    private class ScheduledTimeout<V> extends FutureTask<V> implements ScheduledFuture<V> {\n        private volatile GSource source;\n        private Callable<Boolean> delayCallback = new Callable<Boolean>() {\n            public Boolean call() {\n                // Now start the periodic timer\n                if (period != 0 && !isCancelled()) {\n                    start(period, periodCallback);\n                }\n                // If periodic, don't bother returning a result\n                if (period != 0) {\n                    runAndReset();\n                } else {\n                    run();\n                }\n                return false;\n            }\n        };\n        private Callable<Boolean> periodCallback = new Callable<Boolean>() {\n            public Boolean call() {\n                runAndReset();\n                return !isCancelled();\n            }\n        };\n        private final long period;\n        private final TimeUnit units;\n        \n        public ScheduledTimeout(Callable<V> call, long delay, TimeUnit units) {\n            this(call, delay, 0, units);\n        }\n        public ScheduledTimeout(Callable<V> call, long delay, long period, TimeUnit units) {\n            super(call);\n\n            this.period = period;\n            this.units = units;\n            start(delay, delayCallback);\n        }\n        \n        private final int getMilliseconds(long time) {\n            return (int) units.toMillis(time);\n        }\n        \n        private void start(long timeout, Callable<Boolean> callback) {\n            int milliseconds = getMilliseconds(timeout);\n            /*\n            * If the timeout is a multiple of seconds, use the more efficient\n            * g_timeout_add_seconds, if it is available.\n            */\n            if ((milliseconds % 1000) == 0) {\n                try {\n                    source = GLIB_API.g_timeout_source_new_seconds(milliseconds / 1000);\n                } catch (UnsatisfiedLinkError e) {\n                    source = GLIB_API.g_timeout_source_new(milliseconds);\n                }\n            } else {\n                source = GLIB_API.g_timeout_source_new(milliseconds);\n            }\n            source.setCallback(callback);\n            source.attach(context);\n        }\n        public long getDelay(TimeUnit units) {\n            throw new UnsupportedOperationException(\"Not supported yet.\");\n        }\n\n        public int compareTo(Delayed delayed) {\n            //return delayed.getDelay(TimeUnit.MILLISECONDS)\n            throw new UnsupportedOperationException(\"Not supported yet.\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/glib/NativeEnum.java",
    "content": "/*\n * Copyright (c) 2020 Neil C Smith\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.glib;\n\n/**\n * Interface for enums that wrap a native int-based enum.\n *\n * @param <T> Java enum type\n */\npublic interface NativeEnum<T extends Enum<T>> {\n\n    public int intValue();\n\n    /**\n     * Convert a native int value to the specified NativeEnum type.\n     *\n     * @param <T> enum type\n     * @param type enum class\n     * @param intValue native int value\n     * @return enum value\n     * @throws IllegalArgumentException if no enum value matches the specified\n     * native int value\n     */\n    public static <T extends Enum<T> & NativeEnum<T>> T fromInt(Class<T> type, int intValue) {\n        for (T value : type.getEnumConstants()) {\n            if (value.intValue() == intValue) {\n                return value;\n            }\n        }\n\n        throw new IllegalArgumentException(\"Value \" + intValue + \" is unacceptable for \"\n                + type.getSimpleName() + \" enum\");\n    }\n\n    /**\n     * Convert a native int value to the specified NativeEnum type, allowing for\n     * a default value (or null) to be returned instead of throwing an exception\n     * on invalid values.\n     *\n     * @param <T> enum type\n     * @param type enum class\n     * @param defValue default value to return if no match (may be null)\n     * @param intValue native int value\n     * @return enum value\n     */\n    public static <T extends Enum<T> & NativeEnum<T>> T fromInt(Class<T> type, T defValue, int intValue) {\n        for (T value : type.getEnumConstants()) {\n            if (value.intValue() == intValue) {\n                return value;\n            }\n        }\n\n        return defValue;\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/glib/NativeFlags.java",
    "content": "/* \n * Copyright (c) 2020 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.glib;\n\nimport java.util.EnumSet;\nimport java.util.Set;\n\n/**\n * Interface for enums that represent native bit flags.\n * @param <T> type of flag enum\n */\npublic interface NativeFlags<T extends Enum<T>> extends NativeEnum<T> {\n\n    public static <FLAG extends Enum<FLAG> & NativeFlags<FLAG>> int toInt(Set<FLAG> flags) {\n        int ret = 0;\n        for (FLAG flag : flags) {\n            ret |= flag.intValue();\n        }\n        return ret;\n    }\n    \n    public static <FLAG extends Enum<FLAG> & NativeFlags<FLAG>> int toInt(EnumSet<FLAG> flags) {\n        int ret = 0;\n        for (FLAG flag : flags) {\n            ret |= flag.intValue();\n        }\n        return ret;\n    }\n            \n    public static <FLAG extends Enum<FLAG> & NativeFlags<FLAG>> EnumSet<FLAG>\n            fromInt(Class<FLAG> type, int val) {\n        EnumSet<FLAG> set = EnumSet.allOf(type);\n        set.removeIf(f -> ((val & f.intValue()) == 0));\n        return set;\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/glib/NativeObject.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.glib;\n\nimport java.lang.ref.WeakReference;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.ConcurrentMap;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\nimport com.sun.jna.Pointer;\nimport java.lang.ref.ReferenceQueue;\nimport java.util.Objects;\nimport java.util.ServiceLoader;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.atomic.AtomicReference;\nimport java.util.function.Function;\nimport java.util.stream.Stream;\nimport org.freedesktop.gstreamer.Gst;\nimport org.freedesktop.gstreamer.lowlevel.GPointer;\nimport org.freedesktop.gstreamer.lowlevel.GType;\nimport org.freedesktop.gstreamer.lowlevel.GTypedPtr;\nimport org.freedesktop.gstreamer.lowlevel.GstTypes;\n\n/**\n *\n */\npublic abstract class NativeObject implements AutoCloseable {\n\n    private static final Level LIFECYCLE = Level.FINE;\n    private static final Logger LOG = Logger.getLogger(NativeObject.class.getName());\n    private static final ConcurrentMap<Pointer, NativeRef> INSTANCES = new ConcurrentHashMap<>();\n\n    final Handle handle;\n    private final Pointer ptr;\n\n//    /**\n//     * Creates a new instance of NativeObject\n//     */\n    protected NativeObject(Handle handle) {\n        this.handle = Objects.requireNonNull(handle);\n        this.ptr = handle.ptrRef.get().getPointer();\n        if (handle.isCacheable()) {\n            // need to put all nativeRef in map now so WeakReference doesn't go out of scope\n            INSTANCES.put(this.ptr, new NativeRef(this, handle));\n        }\n    }\n\n    /**\n     * Disown this object. The underlying native object will no longer be\n     * disposed of when this Java object is explicitly or implicitly disposed.\n     * <p>\n     * The underlying reference will remain valid.\n     */\n    public void disown() {\n        LOG.log(LIFECYCLE, \"Disowning \" + getRawPointer());\n        handle.ownsReference.set(false);\n    }\n\n    /**\n     * Implements {@link AutoCloseable#close()} by calling {@link #dispose() }.\n     * <p>\n     * If writing a NativeObject subclass you almost certainly want to override\n     * dispose() to customize behaviour unless you have a very specific reason\n     * that try-with-resources should work differently.\n     */\n    @Override\n    public void close() {\n        dispose();\n    }\n    \n    /**\n     * Dispose this object, and potentially clear (free, unref, etc.) the\n     * underlying native object if this object owns the reference.\n     * <p>\n     * After calling this method this object should not be used.\n     */\n    public void dispose() {\n        LOG.log(LIFECYCLE, \"Disposing object \" + getClass().getName() + \" = \" + handle);\n        handle.dispose();\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        return o instanceof NativeObject && ((NativeObject) o).ptr.equals(ptr);\n    }\n\n    protected GPointer getPointer() {\n        GPointer ptr = handle.ptrRef.get();\n        if (ptr == null) {\n            throw new IllegalStateException(\"Native object has been disposed\");\n        }\n        return ptr;\n    }\n\n    protected Pointer getRawPointer() {\n        GPointer ptr = handle.ptrRef.get();\n        if (ptr == null) {\n            throw new IllegalStateException(\"Native object has been disposed\");\n        }\n        return ptr.getPointer();\n    }\n\n    @Override\n    public int hashCode() {\n        return ptr.hashCode();\n    }\n\n    /**\n     * Invalidate this object without clearing (free, unref, etc.) the\n     * underlying native object.\n     * <p>\n     * After calling this method this object should not be used.\n     */\n    public void invalidate() {\n        LOG.log(LIFECYCLE, () -> \"Invalidating object \" + this + \" = \" + getRawPointer());\n        handle.invalidate();\n    }\n\n    @Override\n    public String toString() {\n        return getClass().getSimpleName() + \"(\" + getRawPointer() + \")\";\n    }\n\n    static <T extends NativeObject> T objectFor(GPointer gptr, Class<T> cls, int refAdjust, boolean ownsHandle) {\n\n        // Ignore null pointers\n        if (gptr == null) {\n            return null;\n        }\n\n        NativeObject obj = NativeObject.instanceFor(gptr.getPointer());\n\n        if (obj != null && cls.isInstance(obj)) {\n            if (ownsHandle && !obj.handle.ownsReference()) {\n                obj.handle.ownsReference.set(true);\n            } else if (refAdjust < 0) {\n                try {\n                    // Lose the extra ref added by gstreamer\n                    ((RefCountedObject.Handle) obj.handle).unref();\n                } catch (ClassCastException ex) {\n                    // A none ref-counted object should not get here!\n                    LOG.log(LIFECYCLE, \"None ref-counted object returned again from caller owns return.\", ex);\n                }\n            }\n            return cls.cast(obj);\n        }\n\n        final GType gtype = gptr instanceof GTypedPtr ? ((GTypedPtr) gptr).getGType() : null;\n        //\n        // For a GObject, MiniObject, ..., use the GType field to find the most\n        // exact class match\n        //\n        if (gtype != null) {\n            TypeRegistration<?> reg = GstTypes.registrationFor(gtype);\n            if (reg != null) {\n                return cls.cast(reg.factory.apply(\n                        new Initializer(gptr, refAdjust > 0, ownsHandle)));\n            }\n        }\n\n        LOG.log(Level.FINE, () -> String.format(\"Unregistered type requested : %s\", cls.getSimpleName()));\n\n        try {\n            Constructor<T> constructor = cls.getDeclaredConstructor(Initializer.class);\n            constructor.setAccessible(true);\n            T retVal = constructor.newInstance(new Initializer(gptr, refAdjust > 0, ownsHandle));\n            //retVal.initNativeHandle(ptr, refAdjust > 0, ownsHandle);\n            return retVal;\n        } catch (SecurityException ex) {\n            throw new RuntimeException(ex);\n        } catch (IllegalAccessException ex) {\n            throw new RuntimeException(ex);\n        } catch (InstantiationException ex) {\n            throw new RuntimeException(ex);\n        } catch (NoSuchMethodException ex) {\n            throw new RuntimeException(ex);\n        } catch (InvocationTargetException ex) {\n            throw new RuntimeException(ex);\n        }\n\n    }\n\n    static NativeObject instanceFor(Pointer ptr) {\n        WeakReference<NativeObject> ref = INSTANCES.get(ptr);\n\n        //\n        // If the reference was there, but the object it pointed to had been collected, remove it from the map\n        //\n        if (ref != null && ref.get() == null) {\n            INSTANCES.remove(ptr);\n        }\n        return ref != null ? ref.get() : null;\n    }\n\n    /**\n     * A class for propagating low level pointer arguments up the constructor\n     * chain.\n     *\n     * @see Natives#initializer(com.sun.jna.Pointer, boolean, boolean)\n     */\n    public static final class Initializer {\n\n        public final GPointer ptr;\n        public final boolean needRef, ownsHandle;\n\n        Initializer(GPointer ptr, boolean needRef, boolean ownsHandle) {\n            this.ptr = ptr;\n            this.needRef = needRef;\n            this.ownsHandle = ownsHandle;\n        }\n\n    }\n\n    private static final class NativeRef extends WeakReference<NativeObject> {\n\n        private static final boolean REAP_ON_EDT = Boolean.getBoolean(\"glib.reapOnEDT\");\n        private static final ReferenceQueue<NativeObject> QUEUE = new ReferenceQueue<>();\n        private static final ExecutorService REAPER\n                = Executors.newSingleThreadExecutor((r) -> {\n                    Thread t = new Thread(r, \"NativeObject Reaper\");\n                    t.setDaemon(true);\n                    return t;\n                });\n\n        static {\n            REAPER.submit(() -> {\n                while (true) {\n                    try {\n                        NativeRef ref = (NativeRef) QUEUE.remove();\n                        LOG.log(LIFECYCLE, () -> \"Disposing of \" + ref.type + \" : \" + ref.handle.ptrRef.get());\n                        if (REAP_ON_EDT) {\n                            Gst.invokeLater(ref.handle::dispose);\n                        } else {\n                            ref.handle.dispose();\n                        }\n                    } catch (Throwable t) {\n                        LOG.log(Level.WARNING, \"Reaper thread exception\", t);\n                    }\n                }\n            });\n        }\n\n        private final Handle handle;\n        private final String type;\n\n        private NativeRef(NativeObject obj, Handle handle) {\n            super(obj, QUEUE);\n            this.type = obj.getClass().getSimpleName();\n            this.handle = handle;\n        }\n\n    }\n\n    /**\n     * A class for managing the underlying native pointer.\n     */\n    protected static abstract class Handle {\n\n        private final AtomicReference<GPointer> ptrRef;\n        private final AtomicBoolean ownsReference;\n\n        /**\n         * Construct a Handle for the supplied native reference.\n         *\n         * @param ptr native reference\n         * @param ownsReference whether the Handle owns the native reference and\n         * should dispose it when itself disposed.\n         */\n        public Handle(GPointer ptr, boolean ownsReference) {\n            this.ptrRef = new AtomicReference<>(ptr);\n            this.ownsReference = new AtomicBoolean(ownsReference);\n        }\n\n        /**\n         * Disown the native reference. After calling this method,\n         * {@link #ownsReference()} will return {@code false}.\n         */\n        public void disown() {\n            ownsReference.set(false);\n        }\n\n        /**\n         * Invalidate the handle. After calling this method, {@link #getPointer()\n         * } will return {@code null}, {@link #ownsReference() } will return\n         * {@code false}, and any NativeObject weak reference cached for this\n         * pointer will be removed. Unlike calling {@link #dispose() } the\n         * native handle will not be disposed - {@link #disposeNativeHandle(org.freedesktop.gstreamer.lowlevel.GPointer)\n         * } will not be called.\n         */\n        public void invalidate() {\n            GPointer ptr = ptrRef.getAndSet(null);\n            ownsReference.set(false);\n            if (ptr != null) {\n                INSTANCES.remove(ptr.getPointer());\n            }\n        }\n\n        /**\n         * Dispose the handle, and dispose the native reference if owned by this\n         * handle. After calling this method, {@link #getPointer()\n         * } will return {@code null}, {@link #ownsReference() } will return\n         * {@code false}, and any NativeObject weak reference cached for this\n         * pointer will be removed.\n         */\n        public void dispose() {\n            GPointer ptr = ptrRef.getAndSet(null);\n            if (ptr != null) {\n                INSTANCES.remove(ptr.getPointer());\n                if (ownsReference.compareAndSet(true, false)) {\n                    disposeNativeHandle(ptr);\n                }\n            }\n        }\n\n        /**\n         * Control whether a WeakReference to the NativeObject wrapping this\n         * Handle should be created and cached. This means that the same\n         * NativeObject instance will be returned for identical native pointers,\n         * and that the Handle will be disposed automatically when the\n         * NativeObject is garbage collected.\n         * <p>\n         * The default implementation always returns {@code true}. Subclasses\n         * may override this behaviour if required.\n         *\n         * @return true if the NativeObject should be cached and automatically\n         * disposed\n         */\n        public boolean isCacheable() {\n            return true;\n        }\n\n        /**\n         * Subclasses should override this method to dispose of the native\n         * reference (free, unref, etc.). The pointer supplied should be used -\n         * {@link #getPointer()} will return {@code null} by the time this\n         * method is called.\n         *\n         * @param ptr native reference\n         */\n        protected abstract void disposeNativeHandle(GPointer ptr);\n\n        /**\n         * Get the native pointer, or null. Subclasses may override to return a\n         * GPointer subclass.\n         *\n         * @return native pointer or null\n         */\n        protected GPointer getPointer() {\n            return ptrRef.get();\n        }\n\n        /**\n         * Test whether this Handle owns the underlying native reference -\n         * should dispose the native reference on {@link #dispose() }.\n         *\n         * @return true if this Handle owns the reference.\n         */\n        protected boolean ownsReference() {\n            return ownsReference.get();\n        }\n    }\n\n    /**\n     * Registration for creating native object subclasses for specific GTypes.\n     *\n     * @see Natives#registration(java.lang.Class, java.lang.String,\n     * java.util.function.Function)\n     * @param <T> type\n     */\n    public static class TypeRegistration<T extends NativeObject> {\n\n        private final Class<T> javaType;\n        private final String gTypeName;\n        private final Function<Initializer, ? extends T> factory;\n\n        TypeRegistration(Class<T> javaType, String gTypeName, Function<Initializer, ? extends T> factory) {\n            this.javaType = javaType;\n            this.gTypeName = gTypeName;\n            this.factory = factory;\n        }\n\n        public Class<T> getJavaType() {\n            return javaType;\n        }\n\n        public String getGTypeName() {\n            return gTypeName;\n        }\n\n        public Function<Initializer, ? extends T> getFactory() {\n            return factory;\n        }\n\n    }\n\n    /**\n     * Register implementations of this interface via the {@link ServiceLoader}\n     * mechanism to provide new native object registrations externally.\n     */\n    public static interface TypeProvider {\n\n        /**\n         * A {@link Stream} of {@link TypeRegistration} to register.\n         *\n         * @return stream of type registrations\n         */\n        public Stream<TypeRegistration<?>> types();\n\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/glib/Natives.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.glib;\n\nimport com.sun.jna.Pointer;\nimport java.util.ServiceLoader;\nimport java.util.function.Function;\nimport org.freedesktop.gstreamer.MiniObject;\nimport org.freedesktop.gstreamer.Structure;\nimport org.freedesktop.gstreamer.lowlevel.GObjectPtr;\nimport org.freedesktop.gstreamer.lowlevel.GPointer;\nimport org.freedesktop.gstreamer.lowlevel.GstMiniObjectPtr;\nimport org.freedesktop.gstreamer.lowlevel.GstStructurePtr;\n\n/**\n * <b>Here be Dragons!</b>\n * <p>\n * This class provides utility functions for working with the underlying native\n * bindings, creating {@link NativeObject} from pointers and extracting native\n * pointers from NativeObjects. It should normally only be necessary to make use\n * of these methods if extending the bindings externally or interacting with\n * other native code.\n */\npublic final class Natives {\n\n    private Natives() {\n    }\n\n    /**\n     * Create a {@link NativeObject.Initializer} for the provided Pointer.\n     * <p>\n     * This initializer will own the handle.\n     * <p>\n     * This initializer will not request a ref increase (only relevant if used\n     * with instance of {@link RefCountedObject})\n     *\n     * @param ptr native pointer\n     * @return initializer\n     */\n    public static final NativeObject.Initializer initializer(Pointer ptr) {\n        NativeObject.Initializer initializer = initializer(ptr, false, true);\n        return initializer;\n    }\n\n    /**\n     * Create a {@link NativeObject.Initializer} for the provided Pointer.\n     * <p>\n     * This initializer will own the handle.\n     *\n     * @param ptr native pointer\n     * @param needRef whether to request a ref increase (only relevant if used\n     * with instance of {@link RefCountedObject})\n     * @return initializer\n     */\n    public static final NativeObject.Initializer initializer(Pointer ptr, boolean needRef) {\n        NativeObject.Initializer initializer = initializer(ptr, needRef, true);\n        return initializer;\n    }\n\n    /**\n     * Create a {@link NativeObject.Initializer} for the provided Pointer.\n     *\n     * @param ptr native pointer\n     * @param needRef whether to request a ref increase (only relevant if used\n     * with instance of {@link RefCountedObject})\n     * @param ownsHandle whether the NativeObject will own the handle, and\n     * should dispose of the native resource when GC'd or explicitly disposed.\n     * @return initializer\n     */\n    public static final NativeObject.Initializer initializer(Pointer ptr, boolean needRef, boolean ownsHandle) {\n        if (ptr == null) {\n            throw new IllegalArgumentException(\"Invalid native pointer\");\n        }\n        return new NativeObject.Initializer(new GPointer(ptr), needRef, ownsHandle);\n    }\n\n\n    /**\n     * Get a {@link NativeObject} instance of the requested type for the\n     * provided Pointer. Will return a cached instance if one already exists.\n     *\n     * @param <T> NativeObject type to return\n     * @param ptr native Pointer\n     * @param cls Class of type T\n     * @param needRef whether to request a ref increase (only relevant if T is\n     * subclass of {@link RefCountedObject})\n     * @param ownsHandle whether the NativeObject will own the handle, and\n     * should dispose of the native resource when GC'd or explicitly disposed.\n     * @return native object of type T\n     */\n    public static <T extends NativeObject> T objectFor(Pointer ptr, Class<T> cls, boolean needRef, boolean ownsHandle) {\n        return objectFor(ptr, cls, needRef ? 1 : 0, ownsHandle);\n    }\n    \n    /**\n     * Get a {@link NativeObject} instance of the requested type for the\n     * provided Pointer. Will return a cached instance if one already exists.\n     *\n     * @param <T> NativeObject type to return\n     * @param ptr native Pointer\n     * @param cls Class of type T\n     * @param needRef whether to request a ref increase (only relevant if T is\n     * subclass of {@link RefCountedObject})\n     * @param ownsHandle whether the NativeObject will own the handle, and\n     * should dispose of the native resource when GC'd or explicitly disposed.\n     * @return native object of type T\n     */\n    public static <T extends NativeObject> T objectFor(GPointer ptr, Class<T> cls, boolean needRef, boolean ownsHandle) {\n        return NativeObject.objectFor(ptr, cls, needRef ? 1 : 0, ownsHandle);\n    }\n\n    /**\n     * Get a {@link NativeObject} instance of the requested type for the\n     * provided Pointer, for use with native functions returning\n     * {@code Transfer Full} or {@code Transfer Floating} results.\n     * <p>\n     * This method will return a cached instance if one already exists. If the\n     * cached instance is a {@link RefCountedObject} this method will release a\n     * reference.\n     *\n     * @param <T> NativeObject type to return\n     * @param ptr native Pointer\n     * @param cls Class of type T\n     * @return native object of type T\n     */\n    public static <T extends NativeObject> T callerOwnsReturn(Pointer ptr, Class<T> cls) {\n        return objectFor(ptr, cls, -1, true);\n    }\n    \n    /**\n     * Get a {@link NativeObject} instance of the requested type for the\n     * provided Pointer, for use with native functions returning\n     * {@code Transfer Full} or {@code Transfer Floating} results.\n     * <p>\n     * This method will return a cached instance if one already exists. If the\n     * cached instance is a {@link RefCountedObject} this method will release a\n     * reference.\n     *\n     * @param <T> NativeObject type to return\n     * @param ptr native Pointer\n     * @param cls Class of type T\n     * @return native object of type T\n     */\n    public static <T extends NativeObject> T callerOwnsReturn(GPointer ptr, Class<T> cls) {\n        return NativeObject.objectFor(ptr, cls, -1, true);\n    }\n\n    private static <T extends NativeObject> T objectFor(Pointer ptr, Class<T> cls, int refAdjust, boolean ownsHandle) {\n        final GPointer gptr = GObject.class.isAssignableFrom(cls) ? new GObjectPtr(ptr)\n                : MiniObject.class.isAssignableFrom(cls) ? new GstMiniObjectPtr(ptr)\n                : Structure.class.isAssignableFrom(cls) ? new GstStructurePtr(ptr)\n                : new GPointer(ptr);\n        return NativeObject.objectFor(gptr, cls, refAdjust, ownsHandle);\n    }\n    \n    /**\n     * Get the underlying raw native Pointer for a {@link NativeObject}.\n     *\n     * @param obj native object\n     * @return native pointer\n     * @throws IllegalStateException if the native reference has been\n     * invalidated or disposed\n     */\n    public static Pointer getRawPointer(NativeObject obj) {\n        return obj.getRawPointer();\n    }\n\n    /**\n     * Get the underlying native typed GPointer for a {@link NativeObject}.\n     *\n     * @param obj native object\n     * @return native typed pointer\n     * @throws IllegalStateException if the native reference has been\n     * invalidated or disposed\n     */\n    public static GPointer getPointer(NativeObject obj) {\n        return obj.getPointer();\n    }\n\n    /**\n     * Return whether underlying native pointer is owned by this object.\n     *\n     * @param obj native object which may hold a reference to native pointer\n     * @return whether underlying native pointer is owned by this object\n     */\n    public static boolean ownsReference(NativeObject obj) {\n        return obj.handle.ownsReference();\n    }\n\n    /**\n     * Returns whether this object is valid or not.\n     *\n     * @param obj native object\n     * @return whether this object is valid or not\n     */\n    public static boolean validReference(NativeObject obj) {\n        return obj.handle.getPointer() != null;\n    }\n\n    /**\n     * Increase the reference count of a {@link RefCountedObject}\n     *\n     * @param <T> type of object\n     * @param obj object to increase reference count on\n     * @return object\n     */\n    public static <T extends RefCountedObject> T ref(T obj) {\n        ((RefCountedObject.Handle) obj.handle).ref();\n        return obj;\n    }\n\n    /**\n     * Decrease the reference count of a {@link RefCountedObject}\n     *\n     * @param <T> type of object\n     * @param obj object to decrease reference count on\n     * @return object\n     */\n    public static <T extends RefCountedObject> T unref(T obj) {\n        ((RefCountedObject.Handle) obj.handle).unref();\n        return obj;\n    }\n\n    /**\n     * Create a {@link NativeObject.TypeRegistration} for linking\n     * {@link NativeObject} subclasses to GTypes.\n     * <p>\n     * Be careful to respect the link between Java type hierarchy of registered\n     * classes and the underlying GType hierarchy. eg. if the GType is a\n     * subclass of GObject then the Java type must extend from {@link GObject}\n     * <p>\n     * The factory function should normally be a constructor reference.\n     * <p>\n     * Registrations can be provided externally using\n     * {@link NativeObject.TypeProvider} instances registered for use with\n     * {@link ServiceLoader}\n     *\n     * @param <T> Java type\n     * @param javaType Java type class\n     * @param gTypeName name of the GType\n     * @param factory a factory function to return an instance of T given a\n     * {@link NativeObject.Initializer}. Normally a constructor reference -\n     * {@code T::new}\n     * @return registration\n     */\n    public static <T extends NativeObject> NativeObject.TypeRegistration<T>\n            registration(Class<T> javaType, String gTypeName, Function<NativeObject.Initializer, ? extends T> factory) {\n        return new NativeObject.TypeRegistration<>(javaType, gTypeName, factory);\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/glib/RefCountedObject.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.glib;\n\nimport org.freedesktop.gstreamer.lowlevel.GPointer;\n\n/**\n * A {@link NativeObject} that has an associated reference count\n */\npublic abstract class RefCountedObject extends NativeObject {\n\n//    /**\n//     * Creates a new instance of RefCountedObject\n//     */\n//    protected RefCountedObject(Initializer init) {\n//        this(new Handle())\n//        if (init.ownsHandle && init.needRef) {\n//            ref();\n//        }\n//    }\n\n    protected RefCountedObject(Handle handle) {\n        super(handle);\n\n    }\n    \n    protected RefCountedObject(Handle handle, boolean needRef) {\n        super(handle);\n        if (needRef) {\n            handle.ref();\n        }\n    }\n    \n\n\n    // overridden in subclasses\n//    protected abstract void ref();\n//\n//    protected abstract void unref();\n\n    protected static abstract class Handle extends NativeObject.Handle {\n\n        public Handle(GPointer ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n\n        protected abstract void ref();\n\n        protected abstract void unref();\n\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/interfaces/ColorBalance.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2009 Tamas Korodi <kotyo@zamba.fm>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.interfaces;\n\nimport java.util.List;\n\nimport org.freedesktop.gstreamer.Element;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback;\n\nimport com.sun.jna.Pointer;\nimport java.util.ArrayList;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstColorBalanceAPI.GSTCOLORBALANCE_API;\n\npublic class ColorBalance extends GstInterface {\n\n    /**\n     * Wraps the {@link Element} in a <tt>ColorBalance</tt> interface\n     *\n     * @param element the element to use as a <tt>ColorBalance</tt>\n     * @return a <tt>ColorBalance</tt> for the element\n     */\n    public static final ColorBalance wrap(Element element) {\n        return new ColorBalance(element);\n    }\n\n    /**\n     * Creates a new ColorBalance instance\n     *\n     * @param element the element that implements the ColorBalance interface\n     */\n    private ColorBalance(Element element) {\n        super(element, GSTCOLORBALANCE_API.gst_color_balance_get_type());\n    }\n\n    /**\n     * Retrieves a list of ColorBalanceChannels from the ColorBalance\n     *\n     * @return a list of color balance channels available on this device\n     */\n    public List<ColorBalanceChannel> getChannelList() {\n        \n        GlibAPI.GList glist = GSTCOLORBALANCE_API.gst_color_balance_list_channels(this);\n        List<ColorBalanceChannel> list = new ArrayList<>();\n        GlibAPI.GList next = glist;\n        while (next != null) {\n            if (next.data != null) {\n                list.add(channelFor(next.data, true));\n            }\n            next = next.next();\n        }\n        return list;\n    }\n        \n    /**\n     * Retrieves a ColorBalanceChannel for the given Pointer\n     *\n     * @param pointer\n     * @param needRef\n     * @return a ColorBalanceChannel instance\n     */\n    private final ColorBalanceChannel channelFor(Pointer pointer,\n            boolean needRef) {\n        return new ColorBalanceChannel(this, pointer, needRef, true);\n    }\n\n    /**\n     * Signal emitted when color balance value changed\n     *\n     * @see #connect(VALUE_CHANGED)\n     * @see #disconnect(VALUE_CHANGED)\n     */\n    public static interface VALUE_CHANGED {\n\n        /**\n         * Called when the color balance channel value changes\n         */\n        public void colorBalanceValueChanged(ColorBalance colorBalance,\n                ColorBalanceChannel channel, int value);\n    }\n\n    /**\n     * Add a listener for norm-changed messages.\n     *\n     * @param listener the listener to be called when the norm changes\n     */\n    public void connect(final VALUE_CHANGED listener) {\n        element.connect(VALUE_CHANGED.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public boolean callback(Pointer colorBalance, ColorBalanceChannel channel, int value) {\n                listener.colorBalanceValueChanged(ColorBalance.this, channel, value);\n                return true;\n            }\n        });\n    }\n\n    /**\n     * Disconnect the listener for norm-changed messages.\n     *\n     * @param listener the listener that was registered to receive the message.\n     */\n    public void disconnect(VALUE_CHANGED listener) {\n        element.disconnect(VALUE_CHANGED.class, listener);\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/interfaces/ColorBalanceChannel.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2009 Tamas Korodi <kotyo@zamba.fm>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.interfaces;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstColorBalanceAPI.GSTCOLORBALANCE_API;\n\nimport org.freedesktop.gstreamer.glib.GObject;\nimport org.freedesktop.gstreamer.lowlevel.GstColorBalanceAPI;\n\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.glib.Natives;\n\npublic class ColorBalanceChannel extends GObject {\n\tpublic static final String GTYPE_NAME = \"GstColorBalanceChannel\";\n\n\tprivate final GstColorBalanceAPI.ColorBalanceChannelStruct struct;\n\tprivate final ColorBalance colorBalance;\n\n\t/**\n\t * For internal gstreamer-java use only\n\t * \n\t * @param init\n\t */\n\tColorBalanceChannel(Initializer init) {\n\t\tsuper(init);\n\t\tthrow new IllegalArgumentException(\"Cannot instantiate\");\n\t}\n\n\tColorBalanceChannel(ColorBalance colorBalance, Pointer ptr,\n\t\t\tboolean needRef, boolean ownsHandle) {\n\t\tsuper(Natives.initializer(ptr, needRef, ownsHandle));\n\t\tstruct = new GstColorBalanceAPI.ColorBalanceChannelStruct(ptr);\n\t\tthis.colorBalance = colorBalance;\n\t}\n\n\tpublic String getName() {\n\t\treturn struct.getLabel();\n\t}\n\n\tpublic int getMinValue() {\n\t\treturn struct.getMinValue();\n\t}\n\n\tpublic int getMaxValue() {\n\t\treturn struct.getMaxValue();\n\t}\n\n\tpublic void setValue(int value) {\n\t\tGSTCOLORBALANCE_API.gst_color_balance_set_value(colorBalance, this, value);\n\t}\n\n\tpublic int getValue(int value) {\n\t\treturn GSTCOLORBALANCE_API.gst_color_balance_get_value(colorBalance, this);\n\t}\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/interfaces/GstInterface.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.interfaces;\n\nimport org.freedesktop.gstreamer.lowlevel.GType;\n\nimport org.freedesktop.gstreamer.Element;\n\nimport org.freedesktop.gstreamer.glib.GObject;\n\n/**\n * Base type for all gstreamer interface proxies\n */\nclass GstInterface implements GObject.GInterface {\n    protected final Element element;\n    protected GstInterface(Element element, GType type) {\n        this.element = element;\n    }\n\n    @Override\n    public Element getGObject() {\n        return element;\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/interfaces/Navigation.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2009 Tamas Korodi <kotyo@zamba.fm>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.interfaces;\n\nimport org.freedesktop.gstreamer.Element;\nimport org.freedesktop.gstreamer.Structure;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstNavigationAPI.GSTNAVIGATION_API;\n\npublic class Navigation extends GstInterface {\n\t/**\n\t * Wraps the {@link Element} in a <tt>Navigation</tt> interface\n\t * \n\t * @param element\n\t *            the element to use as a <tt>Navigation</tt>\n\t * @return a <tt>Navigation</tt> for the element\n\t */\n\tpublic static final Navigation wrap(Element element) {\n\t\treturn new Navigation(element);\n\t}\n\n\t/**\n\t * Creates a new Navigation instance\n\t * \n\t * @param element\n\t *            the element that implements the Navigation interface\n\t */\n\tprivate Navigation(Element element) {\n\t\tsuper(element, GSTNAVIGATION_API.gst_navigation_get_type());\n\t}\n\n\tpublic void sendEvent(Structure structure) {\n\t\tGSTNAVIGATION_API.gst_navigation_send_event(this, structure);\n\t}\n\n\tpublic void sendKeyEvent(String event, String key) {\n\t\tGSTNAVIGATION_API.gst_navigation_send_key_event(this, event, key);\n\t}\n\n\tpublic void sendMouseEvent(String event, int button, double x, double y) {\n\t\tGSTNAVIGATION_API.gst_navigation_send_mouse_event(this, event, button, x, y);\n\t}\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/interfaces/VideoOrientation.java",
    "content": "/* \n * Copyright (c) 2019 Neil c Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2009 Tamas Korodi <kotyo@zamba.fm>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.interfaces;\n\nimport org.freedesktop.gstreamer.Element;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstVideoOrientationAPI.GSTVIDEOORIENTATION_API;\n\npublic class VideoOrientation extends GstInterface {\n\t/**\n\t * Wraps the {@link Element} in a <tt>VideoOrientation</tt> interface\n\t * \n\t * @param element\n\t *            the element to use as a <tt>VideoOrientation</tt>\n\t * @return a <tt>VideoOrientation</tt> for the element\n\t */\n\tpublic static final VideoOrientation wrap(Element element) {\n\t\treturn new VideoOrientation(element);\n\t}\n\n\t/**\n\t * Creates a new VideoOrientation instance\n\t * \n\t * @param element\n\t *            the element that implements the VideoOrientation interface\n\t */\n\tprivate VideoOrientation(Element element) {\n\t\tsuper(element, GSTVIDEOORIENTATION_API.gst_video_orientation_get_type());\n\t}\n\n//\tpublic boolean getHflip(boolean flip) {\n//\t\treturn GSTVIDEOORIENTATION_API.gst_video_orientation_get_hflip(this, flip);\n//\t}\n//\n//\tpublic boolean getVflip(boolean flip) {\n//\t\treturn GSTVIDEOORIENTATION_API.gst_video_orientation_get_vflip(this, flip);\n//\t}\n//\n//\tpublic boolean getHcenter(int center) {\n//\t\treturn GSTVIDEOORIENTATION_API.gst_video_orientation_get_hcenter(this, center);\n//\t}\n//\n//\tpublic boolean getVcenter(int center) {\n//\t\treturn GSTVIDEOORIENTATION_API.gst_video_orientation_get_vcenter(this, center);\n//\t}\n\n\tpublic boolean setHflip(boolean flip) {\n\t\treturn GSTVIDEOORIENTATION_API.gst_video_orientation_set_hflip(this, flip);\n\t}\n\n\tpublic boolean setVflip(boolean flip) {\n\t\treturn GSTVIDEOORIENTATION_API.gst_video_orientation_set_vflip(this, flip);\n\t}\n\n\tpublic boolean setHcenter(int center) {\n\t\treturn GSTVIDEOORIENTATION_API.gst_video_orientation_set_hcenter(this, center);\n\t}\n\n\tpublic boolean setVcenter(int center) {\n\t\treturn GSTVIDEOORIENTATION_API.gst_video_orientation_set_vcenter(this, center);\n\t}\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/interfaces/VideoOverlay.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2009 Levente Farkas <lfarkas@lfarkas.org>\n * Copyright (C) 2009 Tamas Korodi <kotyo@zamba.fm>\n * Copyright (C) 2008 Wayne Meissner\n * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>\n * Copyright (C) 2014 Claus Holst <claus@b-team.dk>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.interfaces;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstVideoOverlayAPI.GSTVIDEOOVERLAY_API;\n\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.BusSyncReply;\nimport org.freedesktop.gstreamer.Element;\nimport org.freedesktop.gstreamer.message.Message;\n\n\n/**\n * Interface for setting/getting a window system resource on elements\n * supporting it to configure a window into which to render a video.\n */\npublic class VideoOverlay extends GstInterface {\n    /**\n     * Wraps the {@link Element} in a <tt>XOverlay</tt> interface\n     * \n     * @param element the element to use as a <tt>XOverlay</tt>\n     * @return a <tt>XOverlay</tt> for the element\n     */\n    public static VideoOverlay wrap(Element element) {\n        return new VideoOverlay(element);\n    }\n\n    /**\n     * Convenience function to check if the given message is a \"prepare-window-handle\".\n     * This useful for setup native window handles with {@link BusSyncReply}.\n     * \n     * @param message\n     * @return\n     */\n    public static boolean isPrepareWindowHandleMessage(Message message) {\n        return GSTVIDEOOVERLAY_API.gst_is_video_overlay_prepare_window_handle_message(message);\n    }\n\n    /**\n     * Creates a new <tt>VideoOverlay</tt> instance\n     * \n     * @param element the element that implements the overlay interface\n     */\n    private VideoOverlay(Element element) {\n        super(element, GSTVIDEOOVERLAY_API.gst_video_overlay_get_type());\n    }\n    \n    /**\n     * Sets the native window for the {@link Element} to use to display video.\n     *\n     * @param handle A native handle to use to display video.\n     */\n    public void setWindowHandle(long handle) {\n      GSTVIDEOOVERLAY_API.gst_video_overlay_set_window_handle(this, new Pointer(handle));\n    }\n       \n    /**\n     * Tell an overlay that it has been exposed. This will redraw the current frame\n     * in the drawable even if the pipeline is PAUSED.\n     */\n    public void expose() {\n      GSTVIDEOOVERLAY_API.gst_video_overlay_expose(this);\n    }\n    \n    /**\n     * Tell an overlay that it should handle events from the window system. \n     * These events are forwared upstream as navigation events. In some window \n     * system, events are not propagated in the window hierarchy if a client is \n     * listening for them. This method allows you to disable events handling \n     * completely from the XOverlay.\n     */\n    public void handleEvent(boolean handle_events) {\n      GSTVIDEOOVERLAY_API.gst_video_overlay_handle_events(this, handle_events);\n    }\n    \n    /**\n     * Configure a subregion as a video target within the window set by \n     * {@link #setWindowHandle(long)}. If this is not used or not supported \n     * the video will fill the area of the window set as the overlay to 100%. \n     * By specifying the rectangle, the video can be overlaid to a specific \n     * region of that window only. After setting the new rectangle one should \n     * call {@link #expose()} to force a redraw. To unset the region pass -1 \n     * for the width and height parameters.\n     * \n     * This method is needed for non fullscreen video overlay in UI toolkits \n     * that do not support subwindows.\n     * \n     * @param x\n     * @param y\n     * @param width\n     * @param height\n     */\n    public boolean setRenderRectangle(int x, int y, int width, int height) {\n    \treturn GSTVIDEOOVERLAY_API.gst_video_overlay_set_render_rectangle(this, x, y, width, height);\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/AppAPI.java",
    "content": "/*\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2009 Andres Colubri\n * Copyright (c) 2008 Wayne Meissner\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.Buffer;\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.FlowReturn;\nimport org.freedesktop.gstreamer.Sample;\nimport org.freedesktop.gstreamer.elements.AppSink;\nimport org.freedesktop.gstreamer.elements.AppSrc;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\nimport org.freedesktop.gstreamer.lowlevel.annotations.Invalidate;\n\nimport com.sun.jna.ptr.LongByReference;\n\n/**\n *\n * @author wayne\n */\npublic interface AppAPI extends com.sun.jna.Library {\n    \n    AppAPI APP_API = GstNative.load(\"gstapp\", AppAPI.class);\n\n    // AppSrc functions\n    GType gst_app_src_get_type();\n\n    void gst_app_src_set_caps(AppSrc appsrc, Caps caps);\n    @CallerOwnsReturn Caps gst_app_src_get_caps(AppSrc appsrc);\n\n    void gst_app_src_set_size(AppSrc appsrc, long size);\n    long gst_app_src_get_size(AppSrc appsrc);\n\n    void gst_app_src_set_stream_type(AppSrc appsrc, AppSrc.StreamType type);\n    AppSrc.StreamType gst_app_src_get_stream_type(AppSrc appsrc);\n\n    void gst_app_src_set_max_bytes(AppSrc appsrc, long max);\n    long gst_app_src_get_max_bytes(AppSrc appsrc);\n\n    void gst_app_src_set_latency(AppSrc appsrc, long min, long max);\n    void gst_app_src_get_latency(AppSrc appsrc, LongByReference min, LongByReference max);\n\n    void gst_app_src_flush_queued(AppSrc appsrc);\n    \n    FlowReturn gst_app_src_push_buffer(AppSrc appsrc, @Invalidate Buffer buffer);\n    FlowReturn gst_app_src_end_of_stream(AppSrc appsrc);\n\n    // AppSink functions\n    GType gst_app_sink_get_type();\n\n    void gst_app_sink_set_caps(AppSink appsink, Caps caps);\n    @CallerOwnsReturn Caps gst_app_sink_get_caps(AppSink appsink);\n\n    boolean gst_app_sink_is_eos(AppSink appsink);\n\n    @CallerOwnsReturn Sample gst_app_sink_pull_preroll(AppSink appsink);\n    @CallerOwnsReturn Sample gst_app_sink_pull_sample(AppSink appsink);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/BaseSinkAPI.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.freedesktop.gstreamer.PadMode;\nimport org.freedesktop.gstreamer.Buffer;\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.ClockReturn;\nimport org.freedesktop.gstreamer.event.Event;\nimport org.freedesktop.gstreamer.FlowReturn;\nimport org.freedesktop.gstreamer.MiniObject;\nimport org.freedesktop.gstreamer.Pad;\nimport org.freedesktop.gstreamer.query.Query;\nimport org.freedesktop.gstreamer.elements.BaseSink;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI.GList;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GstSegmentStruct;\nimport org.freedesktop.gstreamer.lowlevel.GstElementAPI.GstElementClass;\nimport org.freedesktop.gstreamer.lowlevel.GstElementAPI.GstElementStruct;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\nimport org.freedesktop.gstreamer.query.AllocationQuery;\n\nimport com.sun.jna.Callback;\nimport com.sun.jna.Library;\nimport com.sun.jna.Pointer;\n\n/**\n * GstBaseSink methods and structures\n * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/libs/gst/base/gstbasesink.h?h=1.8\n */\npublic interface BaseSinkAPI extends Library {\n    \n    BaseSinkAPI BASESINK_API = GstNative.load(\"gstbase\", BaseSinkAPI.class);\n    \n    int GST_PADDING = GstAPI.GST_PADDING;\n    int GST_PADDING_LARGE = GstAPI.GST_PADDING_LARGE;\n    \n    public static final class GstBaseSinkStruct extends com.sun.jna.Structure {\n        public GstElementStruct element;\n\n        /*< protected >*/\n        public volatile Pad sinkpad;\n        public volatile PadMode pad_mode;\n\n        /*< protected >*/ /* with LOCK */\n        public volatile long offset;\n        public volatile boolean can_activate_pull;\n        public volatile boolean can_activate_push;\n\n        /*< protected >*/ /* with PREROLL_LOCK */\n        public volatile /* GMutex */ Pointer preroll_lock; \n        public volatile /* GCond */ Pointer preroll_cond; \n        public volatile boolean eos;\n        public volatile boolean need_preroll;\n        public volatile boolean have_preroll;\n        public volatile boolean playing_async;\n\n        /*< protected >*/ /* with STREAM_LOCK */\n        public volatile boolean have_newsegment;\n        public volatile GstSegmentStruct segment;\n\n        /*< private >*/ /* with LOCK */\n        public volatile Pointer /* GstClockID */ clock_id;\n        public volatile boolean sync;\n        public volatile boolean flushing;\n        public volatile boolean running;\n\n        public volatile long max_lateness;\n\n        /*< private >*/\n        public volatile Pointer /* GstBaseSinkPrivate */ priv;\n        \n        /*< private >*/\n        public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING_LARGE];\n\n        public GstBaseSinkStruct(Pointer handle) {\n            super(handle);\n        }\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[] {\n                \"element\", \"sinkpad\", \"pad_mode\",\n                \"offset\", \"can_activate_pull\", \"can_activate_push\",\n                \"preroll_lock\", \"preroll_cond\", \n                \"eos\", \"need_preroll\", \"have_preroll\",\n                \"playing_async\", \"have_newsegment\", \"segment\",\n                \"clock_id\", \"sync\",\n                \"flushing\", \"running\", \"max_lateness\", \"priv\",\n                \"_gst_reserved\"\n            });\n        }\n    }\n    \n    // -------------- Callbacks -----------------\n    public static interface GetCaps extends Callback {\n        public Caps callback(BaseSink sink, Caps caps);\n    }\n    public static interface SetCaps extends Callback {\n        public boolean callback(BaseSink sink, Caps caps);\n    }\n    public static interface Fixate extends Callback {\n        public Caps callback(BaseSink sink, Caps caps);\n    }\n    public static interface ActivatePull extends Callback {\n        public boolean callback(BaseSink sink, boolean active);\n    }\n    public static interface GetTimes extends Callback {\n        public void callback(BaseSink sink, Buffer buffer,\n                Pointer /* GstClockTime */ start, Pointer /* GstClockTime */ end);\n    }\n    public static interface ProposeAllocation extends Callback {\n            public boolean callback(BaseSink sink, AllocationQuery query);\n    }\n    public static interface BooleanFunc1 extends Callback {\n        public boolean callback(BaseSink sink);\n    }\n    public static interface QueryNotify extends Callback {\n    \tpublic boolean callback(BaseSink sink, Query query);\n    }\n    public static interface EventNotify extends Callback {\n    \tpublic boolean callback(BaseSink sink, Event event);\n    }\n    public static interface WaitEventNotify extends Callback {\n    \tpublic FlowReturn callback(BaseSink sink, Event event);\n    }\n    public static interface Render extends Callback {\n        public FlowReturn callback(BaseSink sink, Buffer buffer);\n    }\n    public static interface RenderList extends Callback {\n        public FlowReturn callback(BaseSink sink, GList bufferList);\n    }\n\n    public static final class GstBaseSinkClass extends com.sun.jna.Structure {\n        public GstBaseSinkClass() {}\n        public GstBaseSinkClass(Pointer ptr) {\n            super(ptr);\n        }\n\n        //\n        // Actual data members\n        //\n        public GstElementClass parent_class;\n\n        /* get caps from subclass */\n        public GetCaps get_caps;\n\n        /* notify subclass of new caps */\n        public SetCaps set_caps;\n\n        /* fixate sink caps during pull-mode negotiation */\n        public Fixate fixate;\n\n        /* start or stop a pulling thread */\n        public ActivatePull activate_pull;\n\n        /* get the start and end times for syncing on this buffer */\n        public GetTimes get_times;\n\n        /* propose allocation parameters for upstream */\n        public ProposeAllocation propose_allocation;\n\n        /* start and stop processing, ideal for opening/closing the resource */\n        public BooleanFunc1 start;\n        public BooleanFunc1 stop;\n\n        /*\n         * unlock any pending access to the resource. subclasses should unlock\n         * any function ASAP.\n         */\n        public BooleanFunc1 unlock;\n\n        /* Clear a previously indicated unlock request not that unlocking is\n         * complete. Sub-classes should clear any command queue or indicator they\n         * set during unlock\n         */\n        public BooleanFunc1 unlock_stop;\n\n        /* notify subclass of query */\n        public QueryNotify query;\n\n        /* notify subclass of event */\n        public EventNotify event;\n\n        /* wait for eos or gap, subclasses should chain up to parent first */\n        public WaitEventNotify wait_event;\n\n        /* notify subclass of buffer or list before doing sync */\n        public Render prepare;\n        public RenderList prepare_list;\n\n        /* notify subclass of preroll buffer or real buffer */\n        public Render preroll;\n        public Render render;\n\n        /* Render a BufferList */\n        public RenderList render_list;\n\n        /*< private >*/\n        public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING_LARGE];\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[] {\n                \"parent_class\", \"get_caps\", \"set_caps\",\n                \"fixate\", \"activate_pull\", \"get_times\",\n                \"propose_allocation\", \"start\", \"stop\",\n                \"unlock\", \"unlock_stop\", \"query\", \"event\",\n                \"wait_event\", \"prepare\", \"prepare_list\",\n                \"preroll\", \"render\", \"render_list\", \"_gst_reserved\"\n            });\n        }\n    }\n    \n    GType gst_base_sink_get_type();\n\n    FlowReturn gst_base_sink_do_preroll(BaseSink sink, MiniObject obj);\n    FlowReturn gst_base_sink_wait_preroll(BaseSink sink);\n    \n    /* synchronizing against the clock */\n    void gst_base_sink_set_sync(BaseSink sink, boolean sync);\n    boolean gst_base_sink_get_sync(BaseSink sink);\n\n    /* dropping late buffers */\n    void gst_base_sink_set_max_lateness (BaseSink sink, long max_lateness);\n    long gst_base_sink_get_max_lateness(BaseSink sink);\n    \n    /* performing QoS */\n    void gst_base_sink_set_qos_enabled(BaseSink sink, boolean enabled);\n    boolean gst_base_sink_is_qos_enabled(BaseSink sink);\n    \n    /* doing async state changes */\n    void gst_base_sink_set_async_enabled(BaseSink sink, boolean enabled);\n    boolean gst_base_sink_is_async_enabled(BaseSink sink);\n    \n    /* tuning synchronisation */\n    void gst_base_sink_set_ts_offset(BaseSink sink, long offset);\n    long gst_base_sink_get_ts_offset(BaseSink sink);\n\n    /* last buffer */\n    @CallerOwnsReturn Buffer gst_base_sink_get_last_buffer(BaseSink sink);\n    void gst_base_sink_set_last_buffer_enabled(BaseSink sink, boolean enable);\n    boolean gst_base_sink_is_last_buffer_enabled(BaseSink sink);\n\n    /* latency */\n    boolean gst_base_sink_query_latency(BaseSink sink, boolean live, boolean upstream_live, long min_latency, long max_latency);\n    long gst_base_sink_get_latency(BaseSink sink);\n        \n    /* render delay */\n    void gst_base_sink_set_render_delay(BaseSink sink, long delay);\n    long gst_base_sink_get_render_delay(BaseSink sink);\n    \n    /* blocksize */\n    void gst_base_sink_set_blocksize(BaseSink sink, int blocksize);\n    int gst_base_sink_get_blocksize(BaseSink sink);\n    \n    ClockReturn gst_base_sink_wait_clock(BaseSink sink, long time, /* GstlongDiff */ Pointer jitter);\n    FlowReturn gst_base_sink_wait_eos(BaseSink sink, long time, /* GstlongDiff */ Pointer jitter);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/BaseSrcAPI.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.Buffer;\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.event.Event;\nimport org.freedesktop.gstreamer.FlowReturn;\nimport org.freedesktop.gstreamer.Format;\nimport org.freedesktop.gstreamer.Pad;\nimport org.freedesktop.gstreamer.elements.BaseSrc;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GstSegmentStruct;\nimport org.freedesktop.gstreamer.lowlevel.GstElementAPI.GstElementClass;\nimport org.freedesktop.gstreamer.lowlevel.GstElementAPI.GstElementStruct;\n\nimport com.sun.jna.Callback;\nimport com.sun.jna.Library;\nimport com.sun.jna.Pointer;\nimport com.sun.jna.Union;\nimport com.sun.jna.ptr.LongByReference;\nimport java.util.Arrays;\nimport java.util.List;\nimport org.freedesktop.gstreamer.query.Query;\n\n/**\n * GstBaseSrc methods and structures\n * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/libs/gst/base/gstbasesrc.h?h=1.8\n */\npublic interface BaseSrcAPI extends Library {\n    \n    BaseSrcAPI BASESRC_API = GstNative.load(\"gstbase\", BaseSrcAPI.class);\n    \n    int GST_PADDING = GstAPI.GST_PADDING;\n    int GST_PADDING_LARGE = GstAPI.GST_PADDING_LARGE;\n    \n    public static final class GstBaseSrcStruct extends com.sun.jna.Structure {\n        public GstElementStruct element;\n\n        /*< protected >*/\n        public volatile Pad srcpad;\n\n        /* available to subclass implementations */\n        /* MT-protected (with LIVE_LOCK) */\n        public volatile /* GMutex */ Pointer live_lock;\n        public volatile /* GCond */ Pointer live_cond;\n        public volatile boolean is_live;\n        public volatile boolean live_running;\n\n        /* MT-protected (with LOCK) */\n        public volatile int blocksize;\t/* size of buffers when operating push based */\n        public volatile boolean can_activate_push;\t/* some scheduling properties */\n        public volatile boolean random_access;\n\n        public volatile /* GstClockID */ Pointer clock_id;\t/* for syncing */\n\n        /* MT-protected (with STREAM_LOCK) */\n        public volatile GstSegmentStruct segment;\n        /* MT-protected (with STREAM_LOCK) */\n        public volatile boolean\t need_newsegment;\n\n        public volatile int num_buffers;\n        public volatile int num_buffers_left;\n\n        public volatile boolean typefind;\n        public volatile boolean running;\n        public volatile Event pending_seek;\n        \n        public volatile Pointer /* GstBaseSrcPrivate */ priv;\n        \n        /*< private >*/        \n        public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING_LARGE];\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[] {\n                \"element\", \"srcpad\", \n                \"live_lock\", \"live_cond\", \"is_live\", \"live_running\",\n                \"blocksize\", \"can_activate_push\", \"random_access\",\n                \"clock_id\", \"segment\", \"need_newsegment\",\n                \"num_buffers\", \"num_buffers_left\",\n                \"typefind\", \"running\", \"pending_seek\",\n                \"priv\", \"_gst_reserved\"\n            });\n        }\n    }\n    \n    public static final class GstBaseSrcAbiData extends Union {\n        public volatile GstBaseSrcAbi abi;\n        public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING_LARGE - 1];\n    }\n\n    public static final class GstBaseSrcAbi extends com.sun.jna.Structure {\n        public volatile boolean typefind;\n        public volatile boolean running;\n        public volatile Pointer /* GstEvent */ pending_seek;\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"typefind\", \"running\", \"pending_seek\"\n            });\n        }\n    }\n    \n    // -------------- Callbacks -----------------\n    public static interface GetCaps extends Callback {\n        public Caps callback(BaseSrc src, Caps filter);\n    }\n    public static interface SetCaps extends Callback {\n        public boolean callback(BaseSrc src, Caps caps);\n    }\n    public static interface BooleanFunc1 extends Callback {\n        public boolean callback(BaseSrc src);\n    }\n    public static interface DecideAllocation extends Callback {\n        public boolean callback(BaseSrc src, Query query);\n    }\n    \n\n    public static interface GetTimes extends Callback {\n        public void callback(BaseSrc src, Buffer buffer, \n                Pointer /* GstClockTime */ start, Pointer /* GstClockTime */ end);\n    }\n    public static interface GetSize extends Callback {\n        boolean callback(BaseSrc src, LongByReference size);\n    }\n    public static interface EventNotify extends Callback {\n        boolean callback(BaseSrc src, Event event);\n    }\n    public static interface Create extends Callback {\n        public FlowReturn callback(BaseSrc src, long offset, int size,\n                Pointer /* GstBuffer ** */ bufRef);\n    }\n    public static interface Fill extends Callback {\n        public FlowReturn callback(BaseSrc src, long offset, int size,\n                Buffer buffer);\n    }\n    public static interface Seek extends Callback {\n        boolean callback(BaseSrc src, GstSegmentStruct segment);\n    }\n    public static interface QueryFunc extends Callback {\n        boolean callback(BaseSrc src, Query query);            \n    }\n    public static interface Fixate extends Callback {\n        public Caps callback(BaseSrc src, Caps caps);\n    }\n    public static interface PrepareSeek extends Callback {\n        boolean callback(BaseSrc src, Event seek, GstSegmentStruct segment);\n    }\n    \n    public static final class GstBaseSrcClass extends com.sun.jna.Structure {\n        public GstBaseSrcClass() {}\n        public GstBaseSrcClass(Pointer ptr) {\n            useMemory(ptr);\n            read();\n        }\n        \n        //\n        // Actual data members\n        //\n        public GstElementClass parent_class;\n        \n        /*< public >*/\n        /* virtual methods for subclasses */\n\n        /* get caps from subclass */\n        public GetCaps get_caps;\n        /* decide on caps */\n        public BooleanFunc1 negotiate;\n        /* called if, in negotation, caps need fixating */\n        public Fixate fixate;   \n        /* notify the subclass of new caps */\n        public SetCaps set_caps;\n        \n        /* setup allocation query */\n        public DecideAllocation decide_allocation;       \n  \n  \n        /* start and stop processing, ideal for opening/closing the resource */\n        public BooleanFunc1 start;\n        public BooleanFunc1 stop;\n  \n        /* \n         * Given a buffer, return start and stop time when it should be pushed\n         * out. The base class will sync on the clock using these times. \n         */\n        public GetTimes get_times;\n  \n        /* get the total size of the resource in bytes */\n        public GetSize get_size;\n\n        /* check if the resource is seekable */\n        public BooleanFunc1 is_seekable;\n\n        /* Prepare the segment on which to perform do_seek(), converting to the\n        * current basesrc format. */\n        public PrepareSeek prepare_seek_segment;        \n        /* notify subclasses of a seek */\n        public Seek do_seek;\n        \n        /* unlock any pending access to the resource. subclasses should unlock\n        * any function ASAP. */\n        public BooleanFunc1 unlock;\n        /* Clear any pending unlock request, as we succeeded in unlocking */\n        public BooleanFunc1 unlock_stop;\n \n        /* notify subclasses of a query */\n        public QueryFunc query;\n        \n        /* notify subclasses of an event */\n        public EventNotify event;\n\n        /* ask the subclass to create a buffer with offset and size, the default\n        * implementation will call alloc and fill. */\n        public Create create;\n  \n        /* ask the subclass to allocate an output buffer. The default implementation\n        * will use the negotiated allocator. */\n        public Create alloc;\n        \n        public Fill fill;\n        \n        /*< private >*/\n        public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING_LARGE];\n    \n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[] {\n                \"parent_class\",\n                \"get_caps\", \"negotiate\", \"fixate\", \"set_caps\",\n                \"decide_allocation\",\n                \"start\", \"stop\",\n                \"get_times\", \"get_size\", \"is_seekable\",\n                \"prepare_seek_segment\", \"do_seek\",\n                \"unlock\", \"unlock_stop\",\n                \"query\", \"event\", \"create\", \"alloc\", \"fill\",\n                \"_gst_reserved\"\n                \n            });\n        }\n    \n    }\n\n    GType gst_base_src_get_type();\n\n    FlowReturn gst_base_src_wait_playing(BaseSrc src);\n\n    void gst_base_src_set_live(BaseSrc src, boolean live);\n    boolean gst_base_src_is_live(BaseSrc src);\n\n    void gst_base_src_set_format(BaseSrc src, Format format);\n\n    boolean gst_base_src_query_latency(BaseSrc src, boolean[] live, long[] min_latency, long[] max_latency);\n\n    void gst_base_src_set_blocksize(BaseSrc src, long blocksize);\n    long gst_base_src_get_blocksize(BaseSrc src);\n\n    void gst_base_src_set_do_timestamp(BaseSrc src, boolean timestamp);\n    boolean gst_base_src_get_do_timestamp(BaseSrc src);\n\n    boolean gst_base_src_new_seamless_segment(BaseSrc src, long start, long stop, long position);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/BaseTransformAPI.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.Buffer;\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.event.Event;\nimport org.freedesktop.gstreamer.FlowReturn;\nimport org.freedesktop.gstreamer.Pad;\nimport org.freedesktop.gstreamer.PadDirection;\nimport org.freedesktop.gstreamer.elements.BaseTransform;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GstSegmentStruct;\nimport org.freedesktop.gstreamer.lowlevel.GstElementAPI.GstElementClass;\nimport org.freedesktop.gstreamer.lowlevel.GstElementAPI.GstElementStruct;\n\nimport com.sun.jna.Callback;\nimport com.sun.jna.Library;\nimport com.sun.jna.Pointer;\nimport com.sun.jna.ptr.IntByReference;\nimport java.util.Arrays;\nimport java.util.List;\nimport org.freedesktop.gstreamer.query.Query;\n\n/**\n * GstBaseTransform methods and structures\n * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/libs/gst/base/gstbasetransform.h?h=1.8\n */\npublic interface BaseTransformAPI extends Library {\n    \n    BaseTransformAPI BASETRANSFORM_API = GstNative.load(\"gstbase\", BaseTransformAPI.class);\n    \n    int GST_PADDING = GstAPI.GST_PADDING;\n    int GST_PADDING_LARGE = GstAPI.GST_PADDING_LARGE;\n    \n    public static final class GstBaseTransformStruct extends com.sun.jna.Structure {\n        public GstElementStruct element;\n\n        /*< protected >*/\n        /* source and sink pads */\n        public volatile Pad sinkpad;\n        public volatile Pad srcpad;\n\n        /* MT-protected (with STREAM_LOCK) */\n        public volatile boolean have_segment;\n        public volatile GstSegmentStruct segment;\n        /* Default submit_input_buffer places the buffer here,\n        * for consumption by the generate_output method: */\n        public volatile Buffer queued_buf;\n\n        /*< private >*/\n        public volatile Pointer /* GstBaseTransformPrivate */ priv;\n\n        public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING_LARGE - 1];\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"element\", \"sinkpad\", \"srcpad\",\n                \"have_segment\", \"segment\", \"queued_buf\",\n                \"priv\", \"_gst_reserved\"\n            });\n        }\n    }\n\n    \n    public static interface TransformCaps extends Callback {\n        public Caps callback(BaseTransform trans, PadDirection direction, Caps caps, Caps filter);\n    }\n    public static interface FixateCaps extends Callback {\n        public Caps callback(BaseTransform trans, PadDirection direction, Caps caps, Caps othercaps);\n    }\n    public static interface AcceptCaps extends Callback {\n        public boolean callback(BaseTransform trans, PadDirection direction, Caps caps);\n    }\n    public static interface SetCaps extends Callback {\n        public boolean callback(BaseTransform trans, Caps incaps, Caps outcaps);\n    }\n    public static interface QueryFunc extends Callback {\n        public boolean callback(BaseTransform trans, PadDirection direction, Query query);\n    }\n    public static interface DecideAllocation extends Callback {\n        public boolean callback(BaseTransform trans, Query query);\n    }\n    public static interface FilterMeta extends Callback {\n        public boolean callback(BaseTransform trans, Query query, GType api, Pointer /* GstStructure */ params);\n    }\n    public static interface ProposeAllocation extends Callback {\n        public boolean callback(BaseTransform trans, Query decide_query, Query query);\n    }    \n    public static interface TransformSize extends Callback {\n        public boolean callback(BaseTransform trans, PadDirection direction, Caps caps, \n        \t\t\t\t\t\tint size, Caps othercaps, IntByReference othersize);\n    }\n    public static interface GetUnitSize extends Callback {\n        public boolean callback(BaseTransform trans, Caps caps, IntByReference size);\n    }    \n    public static interface BooleanFunc1 extends Callback {\n        public boolean callback(BaseTransform sink);\n    }\n    public static interface EventNotify extends Callback {\n        public boolean callback(BaseTransform trans, Event event);\n    }\n    public static interface PrepareOutput extends Callback {\n        public FlowReturn callback(BaseTransform trans, Buffer input, Pointer /*GstBuffer ** */ outbuf);\n    }\n    public static interface CopyMetadata extends Callback {\n        public boolean callback(BaseTransform trans, Buffer input, Buffer output);\n    }\n    public static interface TransformMeta extends Callback {\n        public boolean callback(BaseTransform trans, Buffer outbuf, Pointer /* GstMeta */ meta, Buffer output);\n    }\n    public static interface BeforeTransform extends Callback {\n        public void callback(BaseTransform trans, Buffer inbuf);\n    }    \n    public static interface Transform extends Callback {\n        public FlowReturn callback(BaseTransform trans, Buffer inbuf, Buffer outbuf);\n    }\n    public static interface TransformIp extends Callback {\n        public FlowReturn callback(BaseTransform trans, Buffer buf);\n    }\n    public static interface SubmitInputBuffer extends Callback {\n        public FlowReturn callback(BaseTransform trans, boolean is_discont, Buffer input);\n    }\n    public static interface GenerateOutput extends Callback {\n        public FlowReturn callback(BaseTransform trans, Pointer /* GstBuffer ** */ outbuf);\n    }\n    \n    \n    \n    \n    public static final class GstBaseTransformClass extends com.sun.jna.Structure {\n        public GstBaseTransformClass() {}\n        public GstBaseTransformClass(Pointer ptr) {\n            useMemory(ptr);\n            read();\n        }\n        \n        //\n        // Actual data members\n        //        \n        public GstElementClass parent_class;\n        \n        /*< public >*/\n        public volatile boolean passthrough_on_same_caps;\n        public volatile boolean transform_ip_on_passthrough;\n        \n        /* virtual methods for subclasses */\n        public TransformCaps transform_caps;\n\n        public FixateCaps fixate_caps;\n        \n        public AcceptCaps accept_caps;\n        \n        public SetCaps set_caps;\n        \n        public QueryFunc query;\n        \n        /* decide allocation query for output buffers */\n        public DecideAllocation decide_allocation;\n        public FilterMeta filter_meta;\n  \n        /* propose allocation query parameters for input buffers */\n        public ProposeAllocation propose_allocation;\n  \n        /* transform size */        \n        public TransformSize transform_size;        \n        public GetUnitSize get_unit_size;\n\n        /* states */       \n        public BooleanFunc1 start;\n        public BooleanFunc1 stop;\n        \n        /* sink and src pad event handlers */\n        public EventNotify sink_event;\n        public EventNotify src_event;\n        public PrepareOutput prepare_output_buffer;\n        \n        /* metadata */\n        public CopyMetadata copy_metadata;\n        public TransformMeta transform_meta;\n        \n        public BeforeTransform before_transform;\n        \n        /* transform */\n        public Transform transform;        \n        public TransformIp transform_ip;\n\n        public SubmitInputBuffer submit_input_buffer;\n        public GenerateOutput generate_output;\n\n        /*< private >*/\n        public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING_LARGE - 2];\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"parent_class\", \"passthrough_on_same_caps\", \"transform_ip_on_passthrough\",\n                \"transform_caps\", \"fixate_caps\", \"accept_caps\", \"set_caps\", \"query\", \n                \"decide_allocation\", \"filter_meta\", \"propose_allocation\",\n                \"transform_size\", \"get_unit_size\",\n                \"start\", \"stop\", \"sink_event\", \"src_event\",\n                \"prepare_output_buffer\", \"copy_metadata\", \"transform_meta\",\n                \"before_transform\", \"transform\", \"transform_ip\",\n                \"submit_input_buffer\", \"generate_output\", \"_gst_reserved\"\n            });            \n        }\n    }\n    \n    GType gst_base_transform_get_type();\n\n    void gst_base_transform_set_passthrough(BaseTransform trans, boolean passthrough);\n    boolean gst_base_transform_is_passthrough(BaseTransform trans);\n\n    void gst_base_transform_set_in_place(BaseTransform trans, boolean in_place);\n    boolean gst_base_transform_is_in_place(BaseTransform trans);\n\n    void gst_base_transform_update_qos(BaseTransform trans, double proportion, long diff, long timestamp);\n    void gst_base_transform_set_qos_enabled(BaseTransform trans, boolean enabled);\n    boolean gst_base_transform_is_qos_enabled(BaseTransform trans);\n\n    void gst_base_transform_set_gap_aware(BaseTransform trans, boolean gap_aware);\n\n    void gst_base_transform_suggest(BaseTransform trans, Caps caps, int size);\n    void gst_base_transform_reconfigure(BaseTransform trans);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/EnumMapper.java",
    "content": "/* \n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport java.lang.reflect.Field;\nimport java.util.EnumSet;\n\nimport org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue;\nimport org.freedesktop.gstreamer.glib.NativeEnum;\n\n/**\n * Maps to and from native int and an Enum value.\n * @author wayne\n */\npublic class EnumMapper {\n    private static final EnumMapper mapper = new EnumMapper();\n    public static EnumMapper getInstance() {\n        return mapper;\n    }\n    \n    public int intValue(Enum<?> value) {\n        return value instanceof NativeEnum ? ((NativeEnum) value).intValue() : value.ordinal();\n    }\n    public <E extends Enum<E>> E valueOf(int value, Class<E> enumClass) {\n        //\n        // Just loop around all the enum values and find one that matches.\n        // Storing the values in a Map might be faster, but by the time you deal\n        // with locking overhead, its hardly worth it for small enums.\n        // \n        if (NativeEnum.class.isAssignableFrom(enumClass)) {\n            for (E e : EnumSet.allOf(enumClass)) {\n                if (((NativeEnum) e).intValue() == value) {\n                    return e;\n                }\n            }\n        } else {\n            for (E e : EnumSet.allOf(enumClass)) {\n                if (e.ordinal() == value) {\n                    return e;\n                }\n            }\n        }\n        //\n        // No value found - try to find the default value for unknown values.\n        // This is useful for enums that aren't fixed in stone and/or where you\n        // don't want to throw an Exception for an unknown value.\n        //\n        try {\n            for (Field f : enumClass.getDeclaredFields()) {\n                if (f.getAnnotation(DefaultEnumValue.class) != null) {\n                    return Enum.valueOf(enumClass, f.getName());\n                }\n            }\n            throw new IllegalArgumentException();\n        } catch (IllegalArgumentException ex) {      \n            //\n            // No default, so just give up and throw an exception\n            //\n            throw new IllegalArgumentException(\"No known Enum mapping for \"\n                    + enumClass.getName() + \" value=\" + value);\n        }\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GBoolean.java",
    "content": "/* \n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\n/**\n *\n */\npublic class GBoolean {\n    public static final int TRUE = 1;\n    public static final int FALSE = 0;\n    public static int valueOf(boolean value) {\n        return value ? 1 : 0;\n    }\n    public static int valueOf(Boolean value) {\n        return Boolean.TRUE.equals(value) ? 1 : 0;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GFunctionMapper.java",
    "content": "/* \n * Copyright (c) 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport java.lang.reflect.Method;\nimport java.util.Arrays;\nimport java.util.List;\n\nimport com.sun.jna.NativeLibrary;\n\n/**\n *\n * @author wayne\n */\npublic class GFunctionMapper implements com.sun.jna.FunctionMapper {\n    private final static List<String> stripPrefixes = Arrays.asList(\"ptr_\");\n\n    public String getFunctionName(NativeLibrary library, Method method) {\n\n        String name = method.getName();\n        for (String prefix : stripPrefixes) {\n            if (name.startsWith(prefix)) {\n                return name.substring(prefix.length());\n            }\n        }\n        // Default to just returning the name\n        return name;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GNative.java",
    "content": "/*\n * Copyright (c) 2021 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport java.lang.reflect.InvocationHandler;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Proxy;\nimport java.util.Map;\n\nimport com.sun.jna.Library;\nimport com.sun.jna.Native;\nimport com.sun.jna.NativeLibrary;\nimport com.sun.jna.Platform;\n\n/**\n *\n */\npublic final class GNative {\n            \n    private final static String[] nameFormats;\n    \n    static {\n        String defFormats = \"%s\";\n        if (Platform.isWindows()) {\n            defFormats = \"%s-0|%s|lib%s-0|lib%s\";\n        } else if (Platform.isMac()) {\n            defFormats = \"%s.0|%s\";\n        }\n        nameFormats = System.getProperty(\"gstreamer.GNative.nameFormats\", defFormats).split(\"\\\\|\");\n    }\n\n    private GNative() {}\n\n    public static synchronized <T extends Library> T loadLibrary(String name, Class<T> interfaceClass, Map<String, ?> options) {\n        for (String format : nameFormats)\n            try {\n                return loadNativeLibrary(String.format(format, name), interfaceClass, options);\n            } catch (UnsatisfiedLinkError ex) {\n                continue;\n            }\n        throw new UnsatisfiedLinkError(\"Could not load library: \" + name);\n    }\n\n    private static <T extends Library> T loadNativeLibrary(String name, Class<T> interfaceClass, Map<String, ?> options) {\n        T library = interfaceClass.cast(Native.loadLibrary(name, interfaceClass, options));\n        boolean needCustom = false;\n    search:\n        for (Method m : interfaceClass.getMethods())\n            for (Class<?> cls : m.getParameterTypes())\n                if (cls.isArray() && getConverter(cls.getComponentType()) != null) {\n                    needCustom = true;\n                    break search;\n                }\n        if (!needCustom)\n            return library;\n//        System.out.println(\"Using custom library proxy for \" + interfaceClass.getName());\n        return interfaceClass.cast(\n        \t\tProxy.newProxyInstance(interfaceClass.getClassLoader(),\n        \t\t\t\tnew Class[]{ interfaceClass }, \n        \t\t\t\tnew Handler<T>(library, options)));\n    }\n\n    public static synchronized NativeLibrary getNativeLibrary(String name) {\n        for (String format : nameFormats)\n            try {\n                return NativeLibrary.getInstance(String.format(format, name));\n            } catch (UnsatisfiedLinkError ex) {\n                continue;\n            }\n        throw new UnsatisfiedLinkError(\"Could not load library: \" + name);\n    }\n\n    private static interface Converter {\n        Class<?> nativeType();\n        Object toNative(Object value);\n        Object fromNative(Object value, Class<?> javaType);\n    }\n\n    private static final Converter enumConverter = new Converter() {\n        public Class<?> nativeType() {\n            return int.class;\n        }\n\n        public Object toNative(Object value) {\n            return value != null ? EnumMapper.getInstance().intValue((Enum<?>) value) : 0;\n        }\n\n        @SuppressWarnings({\"unchecked\",\"rawtypes\"})\n        public Object fromNative(Object value, Class javaType) {\n            return EnumMapper.getInstance().valueOf((Integer) value, javaType);\n        }\n    };\n\n    private static final Converter booleanConverter = new Converter() {\n        public Class<?> nativeType() {\n            return int.class;\n        }\n\n        public Object toNative(Object value) {\n            return value != null ? Boolean.TRUE.equals(value) ? 1 : 0 : 0;\n        }\n        \n        @SuppressWarnings(\"rawtypes\")\n        public Object fromNative(Object value, Class javaType) {\n            return value != null ? ((Integer) value).intValue() != 0 : 0;\n        }\n    };\n\n\n    private static Converter getConverter(Class<?> javaType) {\n        if (Enum.class.isAssignableFrom(javaType))\n            return enumConverter;\n        else if (boolean.class == javaType || Boolean.class == javaType)\n            return booleanConverter;\n        return null;\n    }\n\n    private static class Handler<T> implements InvocationHandler {\n        private final InvocationHandler proxy;\n        @SuppressWarnings(\"unused\") // Keep a reference to stop underlying Library being GC'd\n        private final T library;\n        \n        public Handler(T library, Map<String, ?> options) {\n            this.library = library;\n            this.proxy = Proxy.getInvocationHandler(library);\n        }\n        \n        @SuppressWarnings(\"null\")\n        public Object invoke(Object self, Method method, Object[] args) throws Throwable {\n            int lastArg = args != null ? args.length : 0;\n            if (method.isVarArgs())\n                --lastArg;\n            Runnable[] postInvoke = null;\n            int postCount = 0;\n            for (int i = 0; i < lastArg; ++i) {\n                if (args[i] == null)\n                    continue;\n                final Class<?> cls = args[i].getClass();\n                if (!cls.isArray() || cls.getComponentType().isPrimitive() || cls.getComponentType() == String.class)\n                    continue;\n                final Converter converter = getConverter(cls.getComponentType());\n                if (converter != null) {\n                    final Object[] src = (Object[]) args[i];\n                    final Object dst = java.lang.reflect.Array.newInstance(converter.nativeType(), src.length);\n                    final ArrayIO io = getArrayIO(converter.nativeType());\n                    for (int a = 0; a < src.length; ++a)\n                        io.set(dst, a, converter.toNative(src[a]));\n                    if (postInvoke == null)\n                        postInvoke = new Runnable[lastArg];\n                    postInvoke[postCount++] = new Runnable() {\n                        public void run() {\n                            for (int a = 0; a < src.length; ++a)\n                                src[a] = converter.fromNative(io.get(dst, a), cls.getComponentType());\n                        }\n                    };\n                    args[i] = dst;\n                }\n            }\n            Object retval = proxy.invoke(self, method, args);\n            //\n            // Reload any native arrays into java arrays\n            //\n            for (int i = 0; i < postCount; ++i)\n                postInvoke[i].run();\n            return retval;\n        }\n        \n        @SuppressWarnings(\"unused\")\n        Class<?> getNativeClass(Class<?> cls) {\n            if (cls == Integer.class)\n                return int.class;\n            else if (cls == Long.class)\n                return long.class;\n            return cls;\n        }\n\n        private static interface ArrayIO {\n            public void set(Object array, int index, Object data);\n            public Object get(Object array, int index);\n        }\n\n        private static final ArrayIO intArrayIO = new ArrayIO() {\n            public void set(Object array, int index, Object data) {\n                java.lang.reflect.Array.setInt(array, index, data != null ? (Integer) data : 0);\n            }\n            public Object get(Object array, int index) {\n                return java.lang.reflect.Array.getInt(array, index);\n            }\n        };\n\n        private static final ArrayIO longArrayIO = new ArrayIO() {\n            public void set(Object array, int index, Object data) {\n                java.lang.reflect.Array.setLong(array, index, data != null ? (Long) data : 0);\n            }\n            public Object get(Object array, int index) {\n                return java.lang.reflect.Array.getLong(array, index);\n            }\n        };\n\n        private static ArrayIO getArrayIO(final Class<?> cls) {\n            if (cls == int.class || cls == Integer.class)\n                return intArrayIO;\n            else if (cls == long.class || cls == Long.class)\n                return longArrayIO;\n            throw new IllegalArgumentException(\"No such conversion\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GObjectAPI.java",
    "content": "/*\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2008 Andres Colubri\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\n\nimport org.freedesktop.gstreamer.glib.GObject;\nimport org.freedesktop.gstreamer.glib.GQuark;\nimport org.freedesktop.gstreamer.lowlevel.GValueAPI.GValue;\n\nimport com.sun.jna.Callback;\nimport com.sun.jna.Library;\nimport com.sun.jna.Native;\nimport com.sun.jna.NativeLong;\nimport com.sun.jna.Pointer;\nimport com.sun.jna.Structure.ByReference;\nimport com.sun.jna.ptr.IntByReference;\n\n/**\n *\n */\n@SuppressWarnings(\"serial\")\npublic interface GObjectAPI extends Library {\n    GObjectAPI GOBJECT_API = GNative.loadLibrary(\"gobject-2.0\", GObjectAPI.class,\n        new HashMap<String, Object>() {{\n            put(Library.OPTION_TYPE_MAPPER, new GTypeMapper());\n        }});\n\n    GType g_object_get_type();\n    void g_param_value_validate(GParamSpec spec, GValue data);\n    void g_object_set_property(GObject obj, String property, GValue data);\n    void g_object_get_property(GObject obj, String property, GValue data);\n    void g_object_set(GObject obj, String propertyName, Object... data);\n    void g_object_get(GObject obj, String propertyName, Object... data);\n    Pointer g_object_class_list_properties(Pointer oclass, IntByReference size);\n    \n    Pointer g_object_new(GType object_type, Object... args);\n    \n    interface GClosureNotify extends Callback {\n        void callback(Pointer data, Pointer closure);\n    }\n//    NativeLong g_signal_connect_data(GObject obj, String signal, Callback callback, Pointer data,\n//            GClosureNotify destroy_data, int connect_flags);\n//    void g_signal_handler_disconnect(GObject obj, NativeLong id);\n    NativeLong g_signal_connect_data(GObjectPtr obj, String signal, Callback callback, Pointer data,\n            GClosureNotify destroy_data, int connect_flags);\n    void g_signal_handler_disconnect(GObjectPtr obj, NativeLong id);\n    boolean g_object_is_floating(GObjectPtr obj);\n    /** Sink floating ref \n     * https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-ref-sink \n     */\n    Pointer g_object_ref_sink(Pointer ptr);\n    GObjectPtr g_object_ref_sink(GObjectPtr ptr);\n    interface GToggleNotify extends Callback {\n        void callback(Pointer data, Pointer obj, boolean is_last_ref);\n    }\n    void g_object_add_toggle_ref(Pointer object, GToggleNotify notify, Pointer data);\n    void g_object_remove_toggle_ref(Pointer object, GToggleNotify notify, Pointer data);\n    void g_object_add_toggle_ref(GObjectPtr object, GToggleNotify notify, IntPtr data);\n    void g_object_remove_toggle_ref(GObjectPtr object, GToggleNotify notify, IntPtr data);\n    interface GWeakNotify extends Callback {\n        void callback(IntPtr data, Pointer obj);\n    }\n    void g_object_weak_ref(GObject object, GWeakNotify notify, IntPtr data);\n    void g_object_weak_unref(GObject object, GWeakNotify notify, IntPtr data);\n    Pointer g_object_ref(GObjectPtr object);\n    void g_object_unref(GObjectPtr object);\n\n    GParamSpec g_object_class_find_property(GObjectClass oclass, String property_name);\n    Pointer g_object_class_find_property(Pointer oclass, String property_name);\n    GQuark g_quark_try_string(String string);\n    GQuark g_quark_from_static_string(String string);\n    GQuark g_quark_from_string(String string);\n    String g_quark_to_string(GQuark quark);\n\n    String g_intern_string(String string);\n    String g_intern_static_string(String string);\n    \n    void g_type_init();\n    void g_type_init_with_debug_flags(int flags);\n    String g_type_name(GType type);\n    //GQuark                g_type_qname                   (GType            type);\n    GType g_type_from_name(String name);\n    GType g_type_parent(GType type);\n    int g_type_depth(GType type);\n    Pointer g_type_create_instance(GType type);\n    void g_type_free_instance(Pointer instance);\n    boolean g_type_is_a(GType type, GType is_a_type);\n    \n    GType g_type_register_static(GType parent_type, String type_name,\n        GTypeInfo info, /* GTypeFlags */ int flags);\n    GType g_type_register_static(GType parent_type, Pointer type_name,\n        GTypeInfo info, /* GTypeFlags */ int flags);\n    GType g_type_register_static_simple(GType parent_type, String type_name,\n        int class_size, GClassInitFunc class_init, int instance_size,\n        GInstanceInitFunc instance_init, /* GTypeFlags */ int flags);\n    GType g_type_register_static_simple(GType parent_type, Pointer type_name,\n        int class_size, GClassInitFunc class_init, int instance_size,\n        GInstanceInitFunc instance_init, /* GTypeFlags */ int flags);\n    /* \n     * Basic Type Structures\n     */\n    public static class GTypeClass extends com.sun.jna.Structure {\n\n        /*< private >*/\n        public volatile GType g_type;\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Collections.singletonList(\"g_type\");\n        }\n    }\n    \n    public static final class GTypeClassByReference extends GTypeClass implements ByReference {\n    \t//\n    }\n\n\n    public static final class GTypeInstance extends com.sun.jna.Structure {\n\n        /*< private >*/\n    \tpublic volatile GTypeClassByReference g_class; \n        \n        @Override\n        protected List<String> getFieldOrder() {\n            return Collections.singletonList(\"g_class\");\n        }\n    }                  \n    \n    public static final class GObjectStruct extends com.sun.jna.Structure {\n        public volatile GTypeInstance g_type_instance;\n        public volatile int ref_count;\n        public volatile Pointer qdata;\n        public GObjectStruct() {}\n        public GObjectStruct(GObjectPtr ptr) {\n            super(ptr.getPointer());\n            read();\n        }\n        \n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"g_type_instance\", \"ref_count\", \"qdata\"\n            });\n        }\n           \n    }\n    public static final class GObjectConstructParam {\n        public volatile Pointer spec;\n        public volatile Pointer value;\n    }\n    public static final class GObjectClass extends com.sun.jna.Structure {\n        public volatile GTypeClass g_type_class;\n        public volatile Pointer construct_properties;\n        public Constructor constructor;\n        public SetProperty set_property;\n        public GetProperty get_property;\n        public Dispose dispose;\n        public Finalize finalize;\n        public volatile Pointer dispatch_properties_changed;\n        public Notify notify;\n        public volatile byte[] p_dummy = new byte[8 * Native.POINTER_SIZE];\n        \n        public static interface Constructor extends Callback {\n            public Pointer callback(GType type, int n_construct_properties, \n                    GObjectConstructParam properties);\n        };\n        public static interface SetProperty extends Callback {\n            public void callback(GObject object, int property_id, Pointer value, Pointer spec);\n        }\n        public static interface GetProperty extends Callback {\n            public void callback(GObject object, int property_id, Pointer value, Pointer spec);\n        }\n        public static interface Dispose extends Callback {\n            public void callback(GObject object);\n        }\n        public static interface Finalize extends Callback {\n            public void callback(GObject object);\n        }\n        public static interface Notify extends Callback {\n            public void callback(GObject object, Pointer spec);\n        }\n\n        public GObjectClass() {}\n        public GObjectClass(Pointer ptr) {\n            super(ptr);\n            read();\n        }\n        \n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n               \"g_type_class\", \"construct_properties\", \"constructor\",\n               \"set_property\", \"get_property\", \"dispose\",\n               \"finalize\", \"dispatch_properties_changed\", \"notify\",\n               \"p_dummy\"\n            });\n        }\n        \n    }\n    \n    \n    public static interface GBaseInitFunc extends Callback {\n        public void callback(Pointer g_class);\n    }\n\n    public static interface GBaseFinalizeFunc extends Callback {\n        public void callback(Pointer g_class);\n    }\n\n    public static interface GClassInitFunc extends Callback {\n        public void callback(Pointer g_class, Pointer class_data);\n    }\n\n    public static interface GClassFinalizeFunc extends Callback {\n        public void callback(Pointer g_class, Pointer class_data);\n    }\n    public static interface GInstanceInitFunc extends Callback {\n        void callback(GTypeInstance instance, Pointer g_class);\n    }    \n    public static final class GTypeInfo extends com.sun.jna.Structure {\n        public GTypeInfo() { \n            clear();\n        }\n        public GTypeInfo(Pointer ptr) { \n            super(ptr); \n            read();\n        }\n        /* interface types, classed types, instantiated types */\n        public short class_size;\n        public GBaseInitFunc base_init;\n        public GBaseFinalizeFunc base_finalize;\n        /* interface types, classed types, instantiated types */\n        public GClassInitFunc class_init;\n        public GClassFinalizeFunc class_finalize;\n        public Pointer class_data;\n        /* instantiated types */\n        public short instance_size;\n        public short n_preallocs;\n        \n        public GInstanceInitFunc instance_init;\n\n        /* value handling */\n        public volatile /* GTypeValueTable */ Pointer value_table;                \n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"class_size\", \"base_init\", \"base_finalize\",\n                \"class_init\", \"class_finalize\", \"class_data\",\n                \"instance_size\", \"n_preallocs\", \"instance_init\",\n                \"value_table\"\n            });\n        }\n    }\n\n    public static abstract class GParamSpecTypeSpecific extends com.sun.jna.Structure {\n    \tpublic abstract Object getMinimum();\n    \tpublic abstract Object getMaximum();\n    \tpublic abstract Object getDefault();\n    \t\n        public GParamSpecTypeSpecific() { \n        \tclear(); \n        }\n        public GParamSpecTypeSpecific(Pointer ptr) {\n        \tsuper(ptr);\n        }\n    }\n    public static final class GParamSpecBoolean extends GParamSpecTypeSpecific {\n    \tpublic volatile GParamSpec parent_instance;\n    \tpublic volatile boolean default_value;\n    \t\n    \tpublic Object getMinimum() { return null; }\n    \tpublic Object getMaximum() { return null; }\n    \tpublic Object getDefault() { return default_value; }\n    \t\n        public GParamSpecBoolean(Pointer ptr) {\n            super(ptr);\n            read();\n        }\n        \n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"parent_instance\", \"default_value\"\n            });           \n        }\n    }\n    public static final class GParamSpecInt extends GParamSpecTypeSpecific {\n    \tpublic volatile GParamSpec parent_instance;\n    \tpublic volatile int minimum;\n    \tpublic volatile int maximum;\n    \tpublic volatile int default_value;\n    \t\n    \tpublic Object getMinimum() { return minimum; }\n    \tpublic Object getMaximum() { return maximum; }\n    \tpublic Object getDefault() { return default_value; }\n    \t\n        public GParamSpecInt(Pointer ptr) {\n            super(ptr);\n            read();\n        }\n        \n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"parent_instance\", \"minimum\", \"maximum\",\n                \"default_value\"\n            });           \n        }\n        \n    }\n    public static final class GParamSpecUInt extends GParamSpecTypeSpecific {\n    \tpublic volatile GParamSpec parent_instance;\n    \tpublic volatile int minimum;\n    \tpublic volatile int maximum;\n    \tpublic volatile int default_value;\n    \t\n    \tpublic Object getMinimum() { return ((long)minimum)&0xffffff; }\n    \tpublic Object getMaximum() { return ((long)maximum)&0xffffff; }\n    \tpublic Object getDefault() { return ((long)default_value)&0xffffff; }\n    \t\n        public GParamSpecUInt(Pointer ptr) {\n            super(ptr);\n            read();\n        }\n        \n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"parent_instance\", \"minimum\", \"maximum\",\n                \"default_value\"\n            });           \n        }\n    }\n    public static final class GParamSpecChar extends GParamSpecTypeSpecific {\n    \tpublic volatile GParamSpec parent_instance;\n    \tpublic volatile byte minimum;\n    \tpublic volatile byte maximum;\n    \tpublic volatile byte default_value;\n    \t\n    \tpublic Object getMinimum() { return minimum; }\n    \tpublic Object getMaximum() { return maximum; }\n    \tpublic Object getDefault() { return default_value; }\n    \t\n        public GParamSpecChar(Pointer ptr) {\n            super(ptr);\n            read();\n        }\n        \n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"parent_instance\", \"minimum\", \"maximum\",\n                \"default_value\"\n            });           \n        }\n    }\n    public static final class GParamSpecUChar extends GParamSpecTypeSpecific {\n    \tpublic volatile GParamSpec parent_instance;\n    \tpublic volatile byte minimum;\n    \tpublic volatile byte maximum;\n    \tpublic volatile byte default_value;\n    \t\n    \tpublic Object getMinimum() { return ((short)minimum)&0xff; }\n    \tpublic Object getMaximum() { return ((short)maximum)&0xff; }\n    \tpublic Object getDefault() { return ((short)default_value)&0xff; }\n    \t\n        public GParamSpecUChar(Pointer ptr) {\n            super(ptr);\n            read();\n        }\n        \n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"parent_instance\", \"minimum\", \"maximum\",\n                \"default_value\"\n            });           \n        }\n    }\n    public static final class GParamSpecLong extends GParamSpecTypeSpecific {\n    \tpublic volatile GParamSpec parent_instance;\n    \tpublic volatile NativeLong minimum;\n    \tpublic volatile NativeLong maximum;\n    \tpublic volatile NativeLong default_value;\n    \t\n    \tpublic Object getMinimum() { return minimum; }\n    \tpublic Object getMaximum() { return maximum; }\n    \tpublic Object getDefault() { return default_value; }\n    \t\n        public GParamSpecLong(Pointer ptr) {\n            super(ptr);\n            read();\n        }\n        \n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"parent_instance\", \"minimum\", \"maximum\",\n                \"default_value\"\n            });           \n        }\n    }\n    public static final class GParamSpecInt64 extends GParamSpecTypeSpecific {\n    \tpublic volatile GParamSpec parent_instance;\n    \tpublic volatile long minimum;\n    \tpublic volatile long maximum;\n    \tpublic volatile long default_value;\n    \t\n    \tpublic Object getMinimum() { return minimum; }\n    \tpublic Object getMaximum() { return maximum; }\n    \tpublic Object getDefault() { return default_value; }\n    \t\n        public GParamSpecInt64(Pointer ptr) {\n            super(ptr);\n            read();\n        }\n        \n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"parent_instance\", \"minimum\", \"maximum\",\n                \"default_value\"\n            });           \n        }\n    }\n    public static final class GParamSpecFloat extends GParamSpecTypeSpecific {\n    \tpublic volatile GParamSpec parent_instance;\n    \tpublic volatile float minimum;\n    \tpublic volatile float maximum;\n    \tpublic volatile float default_value;\n    \tpublic volatile float epsilon;\n    \t\n    \tpublic Object getMinimum() { return minimum; }\n    \tpublic Object getMaximum() { return maximum; }\n    \tpublic Object getDefault() { return default_value; }\n    \t\n        public GParamSpecFloat(Pointer ptr) {\n            super(ptr);\n            read();\n        }\n        \n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"parent_instance\", \"minimum\", \"maximum\",\n                \"default_value\", \"epsilon\"\n            });           \n        }\n    }\n    public static final class GParamSpecDouble extends GParamSpecTypeSpecific {\n    \tpublic volatile GParamSpec parent_instance;\n    \tpublic volatile double minimum;\n    \tpublic volatile double maximum;\n    \tpublic volatile double default_value;\n    \tpublic volatile double epsilon;\n    \t\n    \tpublic Object getMinimum() { return minimum; }\n    \tpublic Object getMaximum() { return maximum; }\n    \tpublic Object getDefault() { return default_value; }\n    \t\n        public GParamSpecDouble(Pointer ptr) {\n            super(ptr);\n            read();\n        }\n        \n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"parent_instance\", \"minimum\", \"maximum\",\n                \"default_value\", \"epsilon\"\n            });           \n        }\n    }\n    public static final class GParamSpecString extends GParamSpecTypeSpecific {\n    \tpublic volatile GParamSpec parent_instance;\n    \tpublic volatile String default_value;\n    \tpublic volatile String cset_first;\n    \tpublic volatile String cset_nth;\n    \tpublic volatile byte substitutor;\n    \tpublic volatile int null_fold_if_empty_ensure_non_null;\n\n    \t\n    \tpublic Object getMinimum() { return null; }\n    \tpublic Object getMaximum() { return null; }\n    \tpublic Object getDefault() { return default_value; }\n    \t\n        public GParamSpecString(Pointer ptr) {\n            super(ptr);\n            read();\n        }\n        \n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"parent_instance\", \"default_value\", \"cset_first\",\n                \"cset_nth\", \"substitutor\", \"null_fold_if_empty_ensure_non_null\"\n            });           \n        }\n    }\n    \n    public static final class GParamSpec extends com.sun.jna.Structure {\n        public volatile GTypeInstance g_type_instance;\n        public volatile String g_name;\n        public volatile /* GParamFlags */ int g_flags;\n        public volatile GType value_type;\n        public volatile GType owner_type;\n        /*< private >*/\n        public volatile Pointer _nick;\n        public volatile Pointer _blurb;\n        public volatile Pointer qdata;\n        public volatile int ref_count;\n        public volatile int param_id;      /* sort-criteria */\n        \n        public GParamSpec() {\n            clear();\n        }\n        public GParamSpec(Pointer ptr) {\n            super(ptr);\n            read();\n        }\n        \n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"g_type_instance\", \"g_name\", \"g_flags\",\n                \"value_type\", \"owner_type\", \"_nick\",\n                \"_blurb\", \"qdata\", \"ref_count\",\n                \"param_id\"\n            });           \n        }\n        \n/*\n        public String getName() {\n            return (String) readField(\"g_name\");\n        }\n        public int getFlags() {\n            return (Integer) readField(\"g_flags\");\n        }\n        public GType getValueType() {\n            return (GType) readField(\"value_type\");\n        }\n        public GType getOwnerType() {\n            return (GType) readField(\"owner_type\");\n        }\n\n        public void read() {}\n        public void write() {}\n                 */\n    }\n }\n\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GObjectPtr.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Native;\nimport com.sun.jna.Pointer;\n\n/**\n * Base GObject pointer\n */\npublic class GObjectPtr extends GTypedPtr {\n\n    public GObjectPtr() {\n    }\n\n    public GObjectPtr(Pointer ptr) {\n        super(ptr);\n    }\n\n    @Override\n    public GType getGType() {\n        // Quick getter for GType without allocation\n        // same as : new GObjectStruct(ptr).g_type_instance.g_class.g_type\n        Pointer g_class = getPointer().getPointer(0);\n        if (Native.SIZE_T_SIZE == 8) {\n            return GType.valueOf(g_class.getLong(0));\n        } else if (Native.SIZE_T_SIZE == 4) {\n            return GType.valueOf(((long) g_class.getInt(0)) & 0xffffffffL);\n        } else {\n            throw new IllegalStateException(\"SIZE_T size not supported: \" + Native.SIZE_T_SIZE);\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GPointer.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Pointer;\nimport com.sun.jna.PointerType;\nimport java.util.function.Function;\n\n/**\n * Base GLib pointer\n */\npublic class GPointer extends PointerType {\n    \n    public GPointer() {\n    }\n    \n    public GPointer(Pointer ptr) {\n        super(ptr);\n    }\n    \n    public <T extends GPointer> T as(Class<T> cls, Function<Pointer, T> converter) {\n        if (cls.isInstance(this)) {\n            return cls.cast(this);\n        } else {\n            return converter.apply(this.getPointer());\n        }\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GSignalAPI.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\n\nimport org.freedesktop.gstreamer.glib.GObject;\nimport org.freedesktop.gstreamer.glib.GQuark;\nimport org.freedesktop.gstreamer.lowlevel.GObjectAPI.GClosureNotify;\n\nimport com.sun.jna.Callback;\nimport com.sun.jna.Library;\nimport com.sun.jna.NativeLong;\nimport com.sun.jna.Pointer;\n\n/**\n *\n * @author wayne\n */\n@SuppressWarnings(\"serial\")\npublic interface GSignalAPI extends Library {\n    GSignalAPI GSIGNAL_API = GNative.loadLibrary(\"gobject-2.0\", GSignalAPI.class,\n            new HashMap<String, Object>() {{\n                put(Library.OPTION_TYPE_MAPPER, new GTypeMapper());\n            }});\n\n    public static int G_CONNECT_AFTER = 1 << 0;\n    public static int G_CONNECT_SWAPPED = 1 << 1;\n    \n    public static final class GSignalQuery extends com.sun.jna.Structure {\n    \tpublic int signal_id;\n    \tpublic String signal_name;\n    \tpublic GType itype;\n    \tpublic int /* GSignalFlags */ signal_flags;\n    \tpublic GType return_type; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */\n    \tpublic int n_params;\n    \tpublic Pointer param_types; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"signal_id\", \"signal_name\", \"itype\",\n                \"signal_flags\", \"return_type\", \"n_params\",\n                \"param_types\"\n            });\n        }\n    }\n    \n    NativeLong g_signal_connect_data(GObject obj, String signal, Callback callback, Pointer data,\n            GClosureNotify destroy_data, int connect_flags);\n    void g_signal_handler_disconnect(GObject obj, NativeLong id);\n    \n    int g_signal_lookup(String name, GType itype);\n    String g_signal_name(int signal_id);\n    void g_signal_query(int signal_id, GSignalQuery query);\n    int g_signal_list_ids(GType itype, int[] n_ids);\n\n    void g_signal_emit(GObject obj, int signal_id, GQuark detail, Object... arguments);\n    void g_signal_emit_by_name(GObject obj, String signal, Object... arguments);\n    \n    // Do nothing, but provide a base Callback class that gets automatic type conversion\n    public static interface GSignalCallbackProxy extends com.sun.jna.CallbackProxy {}\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GType.java",
    "content": "/*\n * Copyright (c) 2020 Christophe Lafolet\n * Copyright (c) 2007 Wayne Meissner\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport com.sun.jna.FromNativeContext;\nimport com.sun.jna.IntegerType;\nimport com.sun.jna.Native;\n\nimport static org.freedesktop.gstreamer.lowlevel.GObjectAPI.GOBJECT_API;\n\n/**\n *\n */\n@SuppressWarnings(\"serial\")\npublic class GType extends IntegerType {\n    /** Size of a native <code>GType</code>, in bytes. */\n    public static final int SIZE = Native.SIZE_T_SIZE;\n    private static final int G_TYPE_FUNDAMENTAL_SHIFT = 2;\n\n    private static final Map<Long, GType> gTypeByValues = new ConcurrentHashMap<Long, GType>();\n    private static final Map<String, GType> gTypeByNames = new ConcurrentHashMap<String, GType>();\n    \n    public static final GType INVALID = init(0);\n    public static final GType NONE = init(1);\n    public static final GType INTERFACE = init(2);\n    public static final GType CHAR = init(3);\n    public static final GType UCHAR = init(4);\n    public static final GType BOOLEAN = init(5);\n    public static final GType INT = init(6);\n    public static final GType UINT = init(7);\n    public static final GType LONG = init(8);\n    public static final GType ULONG = init(9);\n    public static final GType INT64 = init(10);\n    public static final GType UINT64 = init(11);\n    public static final GType ENUM = init(12);\n    public static final GType FLAGS = init(13);\n    public static final GType FLOAT = init(14);\n    public static final GType DOUBLE = init(15);\n    public static final GType STRING = init(16);\n    public static final GType POINTER = init(17);\n    public static final GType BOXED = init(18);\n    public static final GType PARAM = init(19);\n    public static final GType OBJECT = init(20);\n    public static final GType VARIANT = init(21);\n\n    // descriptions set in lazy\n    private GType parent;\n    private String name;\n    \n    /**\n     * @param value the fundamental type number.\n     * @return the GType\n     */\n    private static GType init(int value) {\n        return valueOf(value << G_TYPE_FUNDAMENTAL_SHIFT);\n    }\n    \n    protected GType(long t) {\n    \tsuper(SIZE, t);\n    }\n\n    /**\n     * Default constructor needed by NativeMappedConverter\n     */\n    public GType() {\n        this(0L);\n    }\n\n    public static GType valueOf(long value) {\n    \treturn gTypeByValues.computeIfAbsent(value, GType::new);\n    }\n\n    public static GType valueOf(String typeName) {\n    \tGType result = gTypeByNames.get(typeName);\n    \tif (result == null) {\n    \t\tresult = GOBJECT_API.g_type_from_name(typeName);\n    \t\tif (result.equals(INVALID)) {\n    \t\t\t// no type has been registered yet\n    \t\t} else {\n        \t\tgTypeByNames.put(typeName, result);\n        \t\tresult.name = typeName;\n    \t\t}\n    \t}\n    \treturn result;\n    }\n    \n    // FIXME : to move in GstTypes\n    public static GType valueOf(Class<?> javaType) {\n        if (Integer.class == javaType || int.class == javaType) {\n            return INT;\n        } else if (Long.class == javaType || long.class == javaType) {\n            return INT64;\n        } else if (Float.class == javaType || float.class == javaType) {\n            return FLOAT;\n        } else if (Double.class == javaType || double.class == javaType) {\n            return DOUBLE;\n        } else if (String.class == javaType) {\n            return STRING;\n        } else {\n            throw new IllegalArgumentException(\"No GType for \" + javaType);\n        }\n    }\n\n    @Override\n    public Object fromNative(Object nativeValue, FromNativeContext context) {\n        return GType.valueOf(((Number) nativeValue).longValue());\n    }\n\n    /**\n     * Return the direct parent type of the current type.\n     * @return the direct parent type or INVALID if the type has no parent\n     */\n    public GType getParentType() {\n    \tif (this.parent == null) \n    \t\tthis.parent = GOBJECT_API.g_type_parent(this);\n    \treturn this.parent;\n    }\n    \n    public String getTypeName() {\n    \tif (this.name == null) {\n    \t\tthis.name = GOBJECT_API.g_type_name(this);\n    \t\tgTypeByNames.put(this.name, this);\n    \t}\n    \treturn this.name;    \t\n    }\n    \n    @Override\n    public String toString() {\n        String gtypeName = this.equals(INVALID) ? \"invalid\" : this.getTypeName();\n    \treturn \"[\" + gtypeName + \":\" + super.longValue() + \"]\";\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GTypeMapper.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport java.lang.annotation.Annotation;\nimport java.lang.reflect.Method;\nimport java.net.URI;\nimport org.freedesktop.gstreamer.glib.GQuark;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\nimport org.freedesktop.gstreamer.lowlevel.annotations.ConstField;\nimport org.freedesktop.gstreamer.lowlevel.annotations.FreeReturnValue;\nimport org.freedesktop.gstreamer.lowlevel.annotations.IncRef;\nimport org.freedesktop.gstreamer.lowlevel.annotations.Invalidate;\n\nimport com.sun.jna.CallbackParameterContext;\nimport com.sun.jna.FromNativeContext;\nimport com.sun.jna.FromNativeConverter;\nimport com.sun.jna.MethodParameterContext;\nimport com.sun.jna.MethodResultContext;\nimport com.sun.jna.Native;\nimport com.sun.jna.Pointer;\nimport com.sun.jna.StructureReadContext;\nimport com.sun.jna.ToNativeContext;\nimport com.sun.jna.ToNativeConverter;\nimport com.sun.jna.TypeConverter;\nimport org.freedesktop.gstreamer.glib.GObject;\nimport org.freedesktop.gstreamer.glib.NativeObject;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.glib.RefCountedObject;\n\n/**\n *\n * @author wayne\n */\npublic class GTypeMapper extends com.sun.jna.DefaultTypeMapper {\n\n    public GTypeMapper() {\n        addToNativeConverter(URI.class, uriConverter);\n    }\n    private static ToNativeConverter interfaceConverter = new ToNativeConverter() {\n\n        public Object toNative(Object arg, ToNativeContext context) {\n            return arg != null ? Natives.getRawPointer(((GObject.GInterface) arg).getGObject()) : null;\n        }\n\n        public Class<?> nativeType() {\n            return Void.class; // not really correct, but not used in this instance\n        }        \n    };\n    \n    private static TypeConverter nativeObjectConverter = new TypeConverter() {\n        public Object toNative(Object arg, ToNativeContext context) {\n            if (arg == null) {\n                return null;\n            }\n            Pointer ptr = Natives.getRawPointer((NativeObject) arg);\n            \n            //\n            // Deal with any adjustments to the proxy neccessitated by gstreamer\n            // breaking their reference-counting idiom with special cases\n            //\n            if (context instanceof MethodParameterContext) {\n                MethodParameterContext mcontext = (MethodParameterContext) context;\n                Method method = mcontext.getMethod();\n                int index = mcontext.getParameterIndex();\n                Annotation[][] parameterAnnotations = method.getParameterAnnotations();\n                if (index < parameterAnnotations.length) {\n                    Annotation[] annotations = parameterAnnotations[index];\n                    for (int i = 0; i < annotations.length; ++i) {\n                        if (annotations[i] instanceof Invalidate) {\n                            ((NativeObject) arg).invalidate();\n                            break;\n                        } else if (annotations[i] instanceof IncRef) {\n                            Natives.ref((RefCountedObject) arg);\n                        }\n                    }\n                }\n            }\n            return ptr;\n        }\n \n        @SuppressWarnings(value = \"unchecked\")\n        public Object fromNative(Object result, FromNativeContext context) {\n            if (result == null) {\n                return null;\n            }\n            if (context instanceof MethodResultContext) {\n                //\n                // By default, gstreamer increments the refcount on objects \n                // returned from functions, so drop a ref here\n                //\n                boolean ownsHandle = ((MethodResultContext) context).getMethod().isAnnotationPresent(CallerOwnsReturn.class);\n//                int refadj = ownsHandle ? -1 : 0;\n//                return NativeObject.objectFor((Pointer) result, (Class<? extends NativeObject>) context.getTargetType(), refadj, ownsHandle);\n                if (ownsHandle) {\n                    return Natives.callerOwnsReturn((Pointer) result, (Class<? extends NativeObject>) context.getTargetType());\n                } else {\n                    return Natives.objectFor((Pointer) result, (Class<? extends NativeObject>) context.getTargetType(), false, false);\n                }\n            }\n            if (context instanceof CallbackParameterContext) {\n//                return NativeObject.objectFor((Pointer) result, (Class<? extends NativeObject>) context.getTargetType(), 1, true);\n                return Natives.objectFor((Pointer) result, (Class<? extends NativeObject>) context.getTargetType(), true, true);\n            }\n            if (context instanceof StructureReadContext) {\n                StructureReadContext sctx = (StructureReadContext) context;\n                boolean ownsHandle = sctx.getField().getAnnotation(ConstField.class) == null;\n//                return NativeObject.objectFor((Pointer) result, (Class<? extends NativeObject>) context.getTargetType(), 1, ownsHandle);\n                return Natives.objectFor((Pointer) result, (Class<? extends NativeObject>) context.getTargetType(), true, true);\n            }\n            throw new IllegalStateException(\"Cannot convert to NativeObject from \" + context);\n        }\n        \n        public Class<?> nativeType() {\n            return Pointer.class;\n        }\n    };\n    private static TypeConverter enumConverter = new TypeConverter() {\n\n        @SuppressWarnings(value = \"unchecked\")\n        public Object fromNative(Object value, FromNativeContext context) {\n            return EnumMapper.getInstance().valueOf((Integer) value, (Class<? extends Enum>) context.getTargetType());\n        }\n\n        public Class<?> nativeType() {\n            return Integer.class;\n        }\n\n        @SuppressWarnings(\"rawtypes\")\n        public Object toNative(Object arg, ToNativeContext context) {\n            if (arg == null) {\n                return null;\n            }\n            return EnumMapper.getInstance().intValue((Enum) arg);\n        }\n    };\n\n    private TypeConverter stringConverter = new TypeConverter() {\n\n        public Object fromNative(Object result, FromNativeContext context) {\n            if (result == null) {\n                return null;\n            }\n            if (context instanceof MethodResultContext) {\n                MethodResultContext functionContext = (MethodResultContext) context;\n                Method method = functionContext.getMethod();\n                Pointer ptr = (Pointer) result;\n                String s = ptr.getString(0);\n                if (method.isAnnotationPresent(FreeReturnValue.class)\n                    || method.isAnnotationPresent(CallerOwnsReturn.class)) {\n                    GlibAPI.GLIB_API.g_free(ptr);\n                }\n                return s;\n            } else {\n                return ((Pointer) result).getString(0);\n            }           \n        }\n\n        public Class<?> nativeType() {\n            return Pointer.class;\n        }\n\n        public Object toNative(Object arg, ToNativeContext context) {\n            // Let the default String -> native conversion handle it\n            return arg;            \n        }\n    };\n\n    private TypeConverter booleanConverter = new TypeConverter() {\n        public Object toNative(Object arg, ToNativeContext context) {\n            return Integer.valueOf(Boolean.TRUE.equals(arg) ? 1 : 0);\n        }\n\n        public Object fromNative(Object arg0, FromNativeContext arg1) {\n            return Boolean.valueOf(((Integer)arg0).intValue() != 0);\n        }\n\n        public Class<?> nativeType() {\n            return Integer.class;\n        }\n    };\n    private TypeConverter gquarkConverter = new TypeConverter() {\n\n        public Object fromNative(Object arg0, FromNativeContext arg1) {\n            return new GQuark((Integer) arg0);\n        }\n\n        public Class<?> nativeType() {\n            return Integer.class;\n        }\n\n        public Object toNative(Object arg0, ToNativeContext arg1) {\n            return ((GQuark) arg0).intValue();\n        }\n    };\n    \n    private TypeConverter intptrConverter = new TypeConverter() {\n        \n        public Object toNative(Object arg, ToNativeContext context) {\n            return ((IntPtr)arg).value;            \n        }\n\n        public Object fromNative(Object arg0, FromNativeContext arg1) {\n            return new IntPtr(((Number) arg0).intValue());            \n        }\n\n        public Class<?> nativeType() {\n            return Native.POINTER_SIZE == 8 ? Long.class : Integer.class;\n        }\n    };\n//    private TypeConverter querytypeConverter = new TypeConverter() {\n//        \n//        public Object toNative(Object arg, ToNativeContext context) {\n//            return ((QueryType)arg).intValue();\n//        }\n//\n//        public Object fromNative(Object arg0, FromNativeContext arg1) {\n//            return QueryType.valueOf(((Number) arg0).intValue());            \n//        }\n//\n//        public Class<?> nativeType() {\n//            return Integer.class;\n//        }\n//    };\n    private static ToNativeConverter uriConverter = new ToNativeConverter() {\n\n        public Object toNative(Object arg0, ToNativeContext arg1) {\n            URI uri = (URI) arg0;\n            String uriString = uri.toString();\n            // Need to fixup file:/ to be file:/// for gstreamer\n            if (\"file\".equals(uri.getScheme()) && uri.getHost() == null) {\n                final String path = uri.getRawPath();\n                if (com.sun.jna.Platform.isWindows()) {\n                    uriString = \"file:/\" + path;\n                } else {\n                    uriString = \"file://\" + path;\n                }\n            }\n            return uriString;\n        }\n\n        public Class<?> nativeType() {\n            return String.class;\n        }\n    };\n    @SuppressWarnings(\"rawtypes\")\n\tpublic FromNativeConverter getFromNativeConverter(Class type) {\n        if (Enum.class.isAssignableFrom(type)) {\n            return enumConverter;              \n        } else if (NativeObject.class.isAssignableFrom(type)) {\n            return nativeObjectConverter;\n        } else if (Boolean.class == type || boolean.class == type) {\n            return booleanConverter;\n        } else if (String.class == type) {\n            return stringConverter;\n        } else if (IntPtr.class == type) {\n            return intptrConverter;\n        } else if (GQuark.class == type) {\n            return gquarkConverter;\n        }\n        return super.getFromNativeConverter(type);\n    }\n\n    @SuppressWarnings(\"rawtypes\")\n\tpublic ToNativeConverter getToNativeConverter(Class type) {\n        if (NativeObject.class.isAssignableFrom(type)) {\n            return nativeObjectConverter;\n        } else if (GObject.GInterface.class.isAssignableFrom(type)) {\n            return interfaceConverter;\n        } else if (Enum.class.isAssignableFrom(type)) {\n            return enumConverter;\n        } else if (Boolean.class == type || boolean.class == type) {\n            return booleanConverter;\n        } else if (String.class == type) {\n            return stringConverter;        \n        } else if (IntPtr.class == type) {\n            return intptrConverter;\n        } else if (GQuark.class == type) {\n            return gquarkConverter;\n        }\n        return super.getToNativeConverter(type);\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GTypedPtr.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Pointer;\n\n/**\n * Base GLib pointer with GType\n */\npublic abstract class GTypedPtr extends GPointer {\n    \n    public GTypedPtr() {\n    }\n    \n    public GTypedPtr(Pointer ptr) {\n        super(ptr);\n    }\n    \n    public abstract GType getGType();\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GValueAPI.java",
    "content": "/*\n * Copyright (c) 2017 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2008 Andres Colubri\n * Copyright (c) 2008 Wayne Meissner\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\n\nimport org.freedesktop.gstreamer.glib.GObject;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\nimport org.freedesktop.gstreamer.lowlevel.annotations.Invalidate;\n\nimport com.sun.jna.Library;\nimport com.sun.jna.NativeLong;\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.glib.NativeObject;\nimport org.freedesktop.gstreamer.glib.Natives;\n\n/**\n *\n * @author wayne\n */\n@SuppressWarnings(\"serial\")\npublic interface GValueAPI extends Library {\n\n    public interface NoMapperAPI extends Library {\n\n        Pointer g_value_get_object(GValue value);\n\n        Pointer g_value_dup_object(GValue value);\n    }\n\n    NoMapperAPI GVALUE_NOMAPPER_API = GNative.loadLibrary(\"gobject-2.0\", NoMapperAPI.class,\n            new HashMap<String, Object>() {});\n\n    GValueAPI GVALUE_API = GNative.loadLibrary(\"gobject-2.0\", GValueAPI.class,\n            new HashMap<String, Object>() {{\n                put(Library.OPTION_TYPE_MAPPER, new GTypeMapper());\n            }});\n\n    public static final class GValue extends com.sun.jna.Structure {\n    \tpublic static final String GTYPE_NAME = \"GValue\";\n\n        /*< private >*/\n        public volatile GType g_type;\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"g_type\", \"data\"\n            });\n        }\n\n        /* public for GTypeValueTable methods */\n        public static final class GValueData extends com.sun.jna.Union {\n            public volatile int v_int;\n            public volatile long v_long;\n            public volatile long v_int64;\n            public volatile float v_float;\n            public volatile double v_double;\n            public volatile Pointer v_pointer;\n        }\n        public volatile GValueData data[] = new GValueData[2];\n\n        public GValue(GType type) {\n            this();\n            GVALUE_API.g_value_init(this, type);\n        }\n        \n        public GValue(GType type, Object val) {\n            this(type);            \n            setValue(val);\n        }\n        \n        public GValue() {}\n        \n        public GValue(Pointer ptr) {\n            useMemory(ptr);\n            read();\n        }\n        \n        public void reset() {\n        \tGValueAPI.GVALUE_API.g_value_reset(this);\n        }\n\n        private <T> T validateVal(Object val, Class<T> clazz) {\n            return validateVal(val, clazz, false);\n        }\n        \n        private <T> T validateVal(Object val, Class<T> clazz, boolean allowNull) {\n            \n            if (val == null) {\n                if (allowNull) {\n                    return null;\n                } else {\n                    throw new IllegalArgumentException(\"null value not allowed for GType.\" + g_type);\n                }\n            }\n            \n            return clazz.cast(val);\n\n        }\n        \n        public void setValue(Object val) {\n            \n            if (g_type.equals(GType.INT)) { GVALUE_API.g_value_set_int(this, validateVal(val, Integer.class));\n            } else if (g_type.equals(GType.UINT)) { GVALUE_API.g_value_set_uint(this, validateVal(val, Integer.class));\n            } else if (g_type.equals(GType.CHAR)) { GVALUE_API.g_value_set_char(this, validateVal(val, Byte.class));\n            } else if (g_type.equals(GType.UCHAR)) { GVALUE_API.g_value_set_uchar(this, validateVal(val, Byte.class));\n            } else if (g_type.equals(GType.LONG)) { GVALUE_API.g_value_set_long(this, validateVal(val, NativeLong.class));\n            } else if (g_type.equals(GType.ULONG)) { GVALUE_API.g_value_set_ulong(this, validateVal(val, NativeLong.class));\n            } else if (g_type.equals(GType.INT64)) { GVALUE_API.g_value_set_int64(this, validateVal(val, Long.class));\n            } else if (g_type.equals(GType.UINT64)) { GVALUE_API.g_value_set_uint64(this, validateVal(val, Long.class));\n            } else if (g_type.equals(GType.BOOLEAN)) { GVALUE_API.g_value_set_boolean(this, validateVal(val, Boolean.class));\n            } else if (g_type.equals(GType.FLOAT)) { GVALUE_API.g_value_set_float(this, validateVal(val, Float.class));\n            } else if (g_type.equals(GType.DOUBLE)) { GVALUE_API.g_value_set_double(this, validateVal(val, Double.class));\n            } else if (g_type.equals(GType.STRING)) { GVALUE_API.g_value_set_string(this, validateVal(val, String.class));\n            } else if (g_type.equals(GType.OBJECT)) { GVALUE_API.g_value_set_object(this, validateVal(val, GObject.class, true));\n            } else if (g_type.equals(GType.POINTER)) { GVALUE_API.g_value_set_pointer(this, validateVal(val, Pointer.class));            \n            } else {\n                throw new IllegalStateException(\"setValue() not supported yet for GType.\" + g_type);\n            }            \n        }\n        \n        public boolean checkHolds(GType type) {\n        \treturn GVALUE_API.g_type_check_value_holds(this, type);\n        }\n        \n        public GType getType() {\n        \treturn g_type;\n        }\n        \n        public Object getValue() {\n            if (g_type.equals(GType.INT)) { return toInt();\n            } else if (g_type.equals(GType.UINT)) { return toUInt();\n            } else if (g_type.equals(GType.CHAR)) { return toChar();\n            } else if (g_type.equals(GType.UCHAR)) { return toUChar();\n            } else if (g_type.equals(GType.LONG)) { return toLong();\n            } else if (g_type.equals(GType.ULONG)) { return toULong();\n            } else if (g_type.equals(GType.INT64)) { return toInt64();\n            } else if (g_type.equals(GType.UINT64)) { return toUInt64();\n            } else if (g_type.equals(GType.BOOLEAN)) { return toBoolean();\n            } else if (g_type.equals(GType.FLOAT)) { return toFloat();\n            } else if (g_type.equals(GType.DOUBLE)) { return toDouble();\n            } else if (g_type.equals(GType.STRING)) { return toJavaString();\n//            } else if (g_type.equals(GType.OBJECT)) { return toObject();\n            } else if (g_type.equals(GType.POINTER)) { return toPointer();\n            } else if (g_type.equals(GValueArray.GTYPE)) {\n                return new GValueArray(GVALUE_API.g_value_get_boxed(this));\n            } else if (g_type.getParentType().equals(GType.BOXED)) {\n                Class<? extends NativeObject> cls = GstTypes.classFor(g_type);\n                if (cls != null) {\n                    Pointer ptr = GVALUE_API.g_value_get_boxed(this);\n//                    return NativeObject.objectFor(ptr, cls, 1, true);\n                    return Natives.objectFor(ptr, cls, true, true);\n                }\n            }\n//            return GVALUE_API.g_value_get_object(this);  \n            return GVALUE_API.g_value_dup_object(this);  \n        }\n        \n        public Integer toInt() {\n        \treturn g_type.equals(GType.INT) ? new Integer(GVALUE_API.g_value_get_int(this)) : null; \n        }\n        \n        public Integer toUInt() {\n        \treturn g_type.equals(GType.UINT) ? new Integer(GVALUE_API.g_value_get_uint(this)) : null; \n        }\n        \n        public Byte toChar() {\n        \treturn g_type.equals(GType.CHAR) ? new Byte(GVALUE_API.g_value_get_char(this)) : null; \n        }\n        \n        public Byte toUChar() {\n        \treturn g_type.equals(GType.UCHAR) ? new Byte(GVALUE_API.g_value_get_uchar(this)) : null;\n        }\n        \n        public Long toLong() {\n        \treturn g_type.equals(GType.LONG) ? new Long(GVALUE_API.g_value_get_long(this).longValue()) : null;\n        }\n        \n        public Long toULong() {\n        \treturn g_type.equals(GType.ULONG) ? new Long(GVALUE_API.g_value_get_ulong(this).longValue()) : null; \n        }\n        \n        public Long toInt64() {\n        \treturn g_type.equals(GType.INT64)? new Long(GVALUE_API.g_value_get_int64(this)) : null; \n        }\n        \n        public Long toUInt64() {\n        \treturn g_type.equals(GType.UINT64) ? new Long(GVALUE_API.g_value_get_uint64(this)) : null;\n        }\n        \n        public Boolean toBoolean() {\n        \treturn g_type.equals(GType.BOOLEAN) ? new Boolean(GVALUE_API.g_value_get_boolean(this)) : null;\n        }\n        \n        public Float toFloat() {\n        \treturn g_type.equals(GType.FLOAT) ? new Float(GVALUE_API.g_value_get_float(this)) : null;\n        }\n        \n        public Double toDouble() {\n        \treturn g_type.equals(GType.DOUBLE) ? new Double(GVALUE_API.g_value_get_double(this)) : null;\n        }\n        \n        public String toJavaString() {\n        \treturn g_type.equals(GType.STRING) ? GVALUE_API.g_value_get_string(this) : null;\n        }\n        \n        public Object toObject() {\n        \treturn g_type.equals(GType.OBJECT) ? GVALUE_API.g_value_get_object(this) : null;\n        }\n        \n        public Pointer toPointer() {\n        \treturn g_type.equals(GType.POINTER) ? GVALUE_API.g_value_get_pointer(this) : null;\n        }\n        \n        public String toString() {\n        \treturn GVALUE_API.g_strdup_value_contents(this);\n        }\n    }\n    \n    public static final class GValueArray extends com.sun.jna.Structure {\n    \tpublic static final String GTYPE_NAME = \"GValueArray\";\n        static final GType GTYPE = GType.valueOf(GTYPE_NAME);\n\n    \tpublic volatile int n_values;\n        public volatile Pointer values;\n        //< private >\n        public volatile int n_prealloced;\n\n        private boolean ownsMemory;\n        private static final Pointer NO_MEMORY_POINTER = new Pointer(0);\n\n        public GValueArray() {\n            this(0);\n        }\n        \n        public GValueArray(int n_prealloced) {\n            this(n_prealloced, true);\n        }\n        \n        public GValueArray(int n_prealloced, boolean ownsMemory) {\n            this(GVALUE_API.g_value_array_new(n_prealloced));\n            this.ownsMemory = ownsMemory;\n        }\n        \n        public GValueArray(Pointer pointer) {\n            super(pointer);\n            if (pointer != Pointer.NULL && !NO_MEMORY_POINTER.equals(pointer))\n            \tn_values = pointer.getInt(0);\n        }\n        \n        @SuppressWarnings(\"unused\")\n        private static GValueArray valueOf(Pointer ptr) {\n            return ptr != null ? new GValueArray(ptr) : null;\n        }\n\n        public int getNValues() {\n            return n_values;\n        }\n\n        public GValueArray prepend(GValue value) {            \n            GVALUE_API.g_value_array_prepend(this, value);\n            return this;\n        }\n        \n        public GValueArray append(GValue value) {            \n            GVALUE_API.g_value_array_append(this, value);\n            return this;\n        }\n        \n        public GValueArray insert(int index, GValue value) {            \n            GVALUE_API.g_value_array_insert(this, index, value);\n            return this;\n        }\n        \n        public GValueArray remove(int index) {            \n            GVALUE_API.g_value_array_remove(this, index);\n            return this;\n        }\n        \n        public GValue nth(int i) {\n            return GVALUE_API.g_value_array_get_nth(this, i);\n        }\n        \n        public Object getValue(int i) {            \n            GValue v = nth(i);            \n            return v == null ? null : v.getValue();\n        }\n        \n        public void free() {\n            if (ownsMemory) {\n                GVALUE_API.g_value_array_free(this);  \n                ownsMemory = false;\n            }\n        }\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"n_values\", \"values\", \"n_prealloced\"\n            });\n        }\n    }\n    \n    GValue g_value_init(GValue value, GType g_type);\n    GValue g_value_reset(GValue value);\n    void g_value_unset(GValue value);\n    void g_value_set_char(GValue value, byte v_char);\n    byte g_value_get_char(GValue value);\n    void g_value_set_uchar(GValue value, byte v_uchar);\n    byte g_value_get_uchar(GValue value);\n    void g_value_set_boolean(GValue value, boolean v_boolean);\n    boolean g_value_get_boolean(GValue value);\n    void g_value_set_int(GValue value, int v_int);\n    int g_value_get_int(GValue value);\n    void g_value_set_uint(GValue value, int v_int);\n    int g_value_get_uint(GValue value);\n    void g_value_set_long(GValue value, NativeLong v_long);\n    NativeLong g_value_get_long(GValue value);\n    void g_value_set_ulong(GValue value, NativeLong v_long);\n    NativeLong g_value_get_ulong(GValue value);\n    void g_value_set_int64(GValue value, long v_int64);\n    long g_value_get_int64(GValue value);\n    void g_value_set_uint64(GValue value, long v_uint64);\n    long g_value_get_uint64(GValue value);\n    void g_value_set_float(GValue value, float v_float);\n    float g_value_get_float(GValue value);\n    void g_value_set_double(GValue value, double v_double);\n    double g_value_get_double(GValue value);\n    void g_value_set_enum(GValue value, int v_enum);\n    int g_value_get_enum(GValue value);\n    void g_value_set_string(GValue value, String v_string);\n    void g_value_set_static_string (GValue value, String v_string);\n    String g_value_get_string(GValue value);\n    Pointer g_value_get_pointer(GValue value);\n    void g_value_set_pointer(GValue value, Pointer pointer);\n    boolean g_value_type_compatible(GType src_type, GType dest_type);\n    boolean g_value_type_transformable(GType src_type, GType dest_type);\n    boolean g_value_transform(GValue src_value, GValue dest_value);\n    \n    @CallerOwnsReturn String g_strdup_value_contents(GValue value);\n    \n    void g_value_set_object(GValue value, GObject v_object);\n    void g_value_take_object(GValue value, @Invalidate GObject v_object);\n    GObject g_value_get_object(GValue value);\n    @CallerOwnsReturn GObject g_value_dup_object(GValue value);\n   \n    Pointer g_value_get_boxed(GValue value);\n\n    GValue g_value_array_get_nth(GValueArray value_array, int index);\n    Pointer g_value_array_new(int n_prealloced);\n    void g_value_array_free (GValueArray value_array);\n\n    Pointer g_value_array_copy(GValueArray value_array);\n    Pointer g_value_array_prepend(GValueArray value_array, GValue value);\n    Pointer g_value_array_append(GValueArray value_array, GValue value);\n    Pointer g_value_array_insert(GValueArray value_array, int index_, GValue value);\n    Pointer g_value_array_remove(GValueArray value_array, int index);\n    \n    boolean g_type_check_value_holds(GValue value, GType type);\n\n/*\n * GCompareDataFunc needs to be implemented.\nPointer g_value_array_sort(GValueArray value_array, GCompareFunc compare_func);\nPointer g_value_array_sort_with_data (GValueArray value_array,\n        GCompareDataFunc compare_func, Pointer user_data);\n */\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GValueStruct.java",
    "content": "/* \n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Structure;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n *\n */\npublic class GValueStruct extends Structure {\n    public volatile int g_type;\n    /** Creates a new instance of GValueStruct */\n    public GValueStruct() {\n    }\n\n    @Override\n    protected List<String> getFieldOrder() {\n        return Collections.singletonList(\"g_type\");\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GioAPI.java",
    "content": "/* \n * Copyright (c) 2021 Neil C Smith\n * Copyright (c) 2016 Isaac Raño Jares\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Library;\nimport com.sun.jna.Pointer;\nimport java.util.Collections;\n\npublic interface GioAPI extends Library {\n\t\n    public static final GioAPI GIO_API =\n            GNative.loadLibrary(\"gio-2.0\", GioAPI.class, Collections.emptyMap());\n\n    // GInetAddress\n    public String g_inet_address_to_string(Pointer gInetAddress);\n\n    // GstSocketAddress\n    public Pointer g_inet_socket_address_new_from_string(String address, int port);\n\n    // GstSocket\n    public Pointer g_socket_new(int gSocketFamilyEnumValue, int gSocketTypeEnumValue, int gSocketProtcolEnumValue, Pointer gErrorStructArrayPointer);\n    public boolean g_socket_bind(Pointer gSocketPointer, Pointer gSocketAddressPointer, boolean allowReuse, Pointer gErrorStructArrayPointer);\n    public boolean g_socket_connect(Pointer gSocketPointer, Pointer gSocketAddressPointer, Pointer gCancellablePointer, Pointer gErrorStructArrayPointer);\n\n    // GCancellable\n    public Pointer g_cancellable_new();\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GlibAPI.java",
    "content": "/* \n * Copyright (c) 2025 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.List;\n\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\n\nimport com.sun.jna.Callback;\nimport com.sun.jna.Library;\nimport com.sun.jna.NativeLong;\nimport com.sun.jna.Pointer;\nimport com.sun.jna.ptr.PointerByReference;\nimport org.freedesktop.gstreamer.glib.GMainContext;\nimport org.freedesktop.gstreamer.glib.GSource;\n\n/**\n *\n */\n@SuppressWarnings(\"serial\")\npublic interface GlibAPI extends Library {\n    GlibAPI GLIB_API = GNative.loadLibrary(\"glib-2.0\", GlibAPI.class,\n            new HashMap<String, Object>() {{\n                put(Library.OPTION_TYPE_MAPPER, new GTypeMapper());\n            }});\n\t\n    public static final int GLIB_SYSDEF_AF_UNIX  = 1;\n    public static final int GLIB_SYSDEF_AF_INET  = 2;\n    public static final int GLIB_SYSDEF_AF_INET6 = 23;\n\n    Pointer g_main_loop_new(GMainContext context, boolean running);\n    void g_main_loop_run(MainLoop loop);\n    boolean g_main_loop_is_running(MainLoop loop);\n    @CallerOwnsReturn GMainContext g_main_loop_get_context(MainLoop loop);\n    void g_main_loop_quit(MainLoop loop);\n    void g_main_loop_ref(GPointer ptr);\n    void g_main_loop_unref(GPointer ptr);\n    \n    /*\n     * GMainContext functions\n     */\n    \n    Pointer g_main_context_new();\n    void g_main_context_ref(GPointer context);\n    void g_main_context_unref(GPointer context);\n    Pointer g_main_context_default();\n    boolean g_main_context_pending(GMainContext ctx);\n    boolean g_main_context_acquire(GMainContext ctx);\n    void g_main_context_release(GMainContext ctx);\n    boolean g_main_context_is_owner(GMainContext ctx);\n    boolean g_main_context_wait(GMainContext ctx);\n    \n    @CallerOwnsReturn GSource g_idle_source_new();\n    @CallerOwnsReturn GSource g_timeout_source_new(int interval);\n    @CallerOwnsReturn GSource g_timeout_source_new_seconds(int interval);\n    int g_source_attach(GSource source, GMainContext context);\n    void g_source_destroy(Pointer source);\n    void g_source_destroy(GSource source);\n    Pointer g_source_ref(Pointer source);\n    void g_source_unref(Pointer source);\n    void g_source_set_callback(GSource source, GSourceFunc callback, Object data, GDestroyNotify destroy);\n    boolean g_source_is_destroyed(Pointer source);\n    boolean g_source_is_destroyed(GSource source);\n    /*\n     * GThread functions\n     */\n    interface GThreadFunc extends Callback {\n        Pointer callback(Pointer data);\n    }\n    Pointer g_thread_create(GThreadFunc func, Pointer data, boolean joinable, PointerByReference error);\n    Pointer g_thread_self();\n    Pointer g_thread_join(Pointer thread);\n    void g_thread_yield();\n    void g_thread_set_priority(Pointer thread, int priority);\n    void g_thread_exit(Pointer retval);\n    \n    \n    \n    interface GSourceFunc extends Callback {\n        boolean callback(Pointer data);\n    }\n    NativeLong g_idle_add(GSourceFunc function, Pointer data);\n    interface GDestroyNotify extends Callback {\n        void callback(Pointer data);\n    }\n    \n    int g_timeout_add(int interval, GSourceFunc function, Pointer data);\n    int g_timeout_add_full(int priority, int interval, GSourceFunc function,\n            Pointer data, GDestroyNotify notify);\n    int g_timeout_add_seconds(int interval, GSourceFunc function, Pointer data);\n    GstAPI.GErrorStruct g_error_new(int quark, int code, String message);\n    void g_error_free(Pointer error);\n    \n    void g_source_remove(int id);\n    void g_free(Pointer ptr);\n    \n//    GType g_date_get_type();\n    Pointer g_date_new();\n    Pointer g_date_new_dmy(int day, int month, int year);\n    Pointer g_date_new_julian(int julian_day);\n    int g_date_get_year(Pointer date);\n    int g_date_get_month(Pointer date);\n    int g_date_get_day(Pointer date);\n    void g_date_free(Pointer date);\n\n    GList g_list_append(GList list, Pointer data);\n\n    public static final class GList extends com.sun.jna.Structure {\n        public volatile Pointer data;\n        public volatile Pointer _next;\n        public volatile Pointer _prev;\n        public GList() {\n            clear();\n        }\n        public GList(Pointer ptr) {\n            useMemory(ptr);\n            read();\n        }\n        public static GList valueOf(Pointer ptr) {\n            return ptr != null ? new GList(ptr) : null;\n        }\n\n        public GList next() {\n            return valueOf(_next);\n        }\n        public GList prev() {\n            return valueOf(_prev);\n        }\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"data\", \"_next\", \"_prev\"\n            });\n        }\n    }\n    public static final class GSList extends com.sun.jna.Structure {\n        public volatile Pointer data;\n        public volatile Pointer _next;\n        public GSList() {\n            clear();\n        }\n        public GSList(Pointer ptr) {\n            useMemory(ptr);\n            read();\n        }\n        public static GSList valueOf(Pointer ptr) {\n            return ptr != null ? new GSList(ptr) : null;\n        }\n\n        public GSList next() {\n            return valueOf(_next);\n        }\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"data\", \"_next\"\n            });\n        }\n    }\n    \n    /*\n     * Miscellaneous Utility Functions\n     */\n    \n    /**\n     * Returns the value of an environment variable.\n     * \n     * On UNIX, the name and value are byte strings which might or might not be \n     * in some consistent character set and encoding. On Windows, they are in UTF-8. \n     * On Windows, in case the environment variable's value contains references \n     * to other environment variables, they are expanded.\n     * \n     * @param variable the environment variable to get.     \n     * @return the value of the environment variable, or NULL if the \n     *         environment variable is not found. \n     */\n    String g_getenv(String variable);\n    \n    \n    /**\n     * Sets an environment variable. \n     * \n     * On UNIX, both the variable's name and value can be arbitrary byte strings, \n     * except that the variable's name cannot contain '='. \n     * On Windows, they should be in UTF-8.\n     * \n     * @param variable the environment variable to set, must not contain '='. \n     * @param value the value for to set the variable to. \n     * @param overwrite whether to change the variable if it already exists.\n     * @return FALSE if the environment variable couldn't be set.\n     */\n    boolean g_setenv(String variable, String value, boolean overwrite);\n    \n    \n    /**\n     * Removes an environment variable from the environment.\n     * \n     * @param variable the environment variable to remove, must not contain '='. \n     */\n    void g_unsetenv(String variable);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstAPI.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.Format;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\n\nimport com.sun.jna.Library;\nimport com.sun.jna.Pointer;\nimport com.sun.jna.ptr.IntByReference;\nimport com.sun.jna.ptr.PointerByReference;\nimport java.util.Arrays;\nimport java.util.List;\n\n/**\n *\n */\npublic interface GstAPI extends Library {\n    \n    GstAPI GST_API = GstNative.load(GstAPI.class);\n    \n    int GST_PADDING = 4;\n    int GST_PADDING_LARGE = 20;\n        \n    GType gst_type_find_get_type();\n    @CallerOwnsReturn String gst_version_string();\n    void gst_version(long[] major, long[] minor, long[] micro, long[] nano);\n    boolean gst_init(IntByReference argc, PointerByReference argv);\n    boolean gst_init_check(IntByReference argc, PointerByReference argv, Pointer[] err);\n    boolean gst_init_check(IntByReference argc, PointerByReference argv, GErrorStruct[] err);\n    boolean gst_segtrap_is_enabled();\n    void gst_segtrap_set_enabled(boolean enabled);\n    void gst_deinit();\n    \n    /**\n    * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/gst/gstsegment.h?h=1.8\n    *\n    * GstSegment:\n    * @flags: flags for this segment\n    * @rate: the playback rate of the segment\n    * @applied_rate: the already applied rate to the segment\n    * @format: the format of the segment values\n    * @base: the running time (plus elapsed time, see offset) of the segment start\n    * @offset: the amount (in buffer timestamps) that has already been elapsed in\n    *     the segment\n    * @start: the start of the segment in buffer timestamp time (PTS)\n    * @stop: the stop of the segment in buffer timestamp time (PTS)\n    * @time: the stream time of the segment start\n    * @position: the buffer timestamp position in the segment (used internally by\n    *     elements such as sources, demuxers or parsers to track progress)\n    * @duration: the duration of the segment\n    *\n    * A helper structure that holds the configured region of\n    * interest in a media file.\n    */\n    public static final class GstSegmentStruct extends com.sun.jna.Structure {\n\n        public GstSegmentStruct() {\n        }\n\n        public GstSegmentStruct(Pointer p) {\n            super(p);\n        }\n\n        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) {\n            this.flags = flags;\n            this.rate = rate;\n            this.applied_rate = applied_rate;\n            this.format = format;\n            this.base = base;\n            this.offset = offset;\n            this.start = start;\n            this.stop = stop;\n            this.time = time;\n            this.position = position;\n            this.duration = duration;\n        }\n        \n        /*< public >*/\n        public int flags;\n        \n        public double rate;\n        public double applied_rate;\n        \n        public Format format;\n        public long base;\n        public long offset;\n        public long start;\n        public long stop;\n        public long time;\n\n        public long position;\n        public long duration;\n\n        /*< private >*/\n        public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING];\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"flags\", \"rate\", \"applied_rate\",\n                \"format\", \"base\", \"offset\",\n                \"start\", \"stop\", \"time\",\n                \"position\", \"duration\", \"_gst_reserved\"\n            });\n        }\n    };\n    \n    public static final class GErrorStruct extends com.sun.jna.Structure {\n        public volatile int domain; /* GQuark */\n        public volatile int code;\n        public volatile String message;\n        \n        /** Creates a new instance of GError */\n        public GErrorStruct() { clear(); }\n        public GErrorStruct(Pointer ptr) {\n            useMemory(ptr);\n        }\n        public int getCode() {\n            return (Integer) readField(\"code\");\n        }\n        public String getMessage() {\n            return (String) readField(\"message\");\n        }\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"domain\", \"code\", \"message\"\n            });\n        }\n    }\n    // Do nothing, but provide a base Callback class that gets automatic type conversion\n    public static interface GstCallback extends com.sun.jna.Callback {\n        static final com.sun.jna.TypeMapper TYPE_MAPPER = new GTypeMapper();\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstARGBControlBindingPtr.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Pointer;\n\n/**\n * \n */\npublic class GstARGBControlBindingPtr extends GstControlBindingPtr {\n    \n    public GstARGBControlBindingPtr() {\n    }\n    \n    public GstARGBControlBindingPtr(Pointer ptr) {\n        super(ptr);\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstBinAPI.java",
    "content": "/* \n * Copyright (c) 2021 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.Bin;\nimport org.freedesktop.gstreamer.Element;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\n\nimport com.sun.jna.Pointer;\n\n/**\n * GstBin functions\n */\npublic interface GstBinAPI extends com.sun.jna.Library {\n    GstBinAPI GSTBIN_API = GstNative.load(GstBinAPI.class);\n\n    @CallerOwnsReturn Pointer ptr_gst_bin_new(String name);\n    @CallerOwnsReturn Pointer ptr_gst_pipeline_new(String name);\n    @CallerOwnsReturn Bin gst_bin_new(String name);\n    GType gst_bin_get_type();\n    \n    boolean gst_bin_add(Bin bin, Element element);\n    void gst_bin_add_many(Bin bin, Element... elements);\n    boolean gst_bin_remove(Bin bin, Element element);\n    void gst_bin_remove_many(Bin bin, Element... elements);\n    @CallerOwnsReturn Element gst_bin_get_by_name(Bin bin, String name);\n    @CallerOwnsReturn Element gst_bin_get_by_name_recurse_up(Bin bin, String name);\n    @CallerOwnsReturn Element gst_bin_get_by_interface(Bin bin, GType iface);\n    GstIteratorPtr gst_bin_iterate_elements(Bin bin);\n    GstIteratorPtr gst_bin_iterate_sorted(Bin bin);\n    GstIteratorPtr gst_bin_iterate_recurse(Bin bin);\n    GstIteratorPtr gst_bin_iterate_sinks(Bin bin);\n    GstIteratorPtr gst_bin_iterate_sources(Bin bin);\n    GstIteratorPtr gst_bin_iterate_all_by_interface(Bin bin, GType iface);\n\n    //Debugging\n    void gst_debug_bin_to_dot_file (Bin bin, int details, String file_name);\n    void gst_debug_bin_to_dot_file_with_ts (Bin bin, int details, String file_name);\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstBufferAPI.java",
    "content": "/* \n * Copyright (c) 2014 Tom Greenwood <tgreenwood@cafex.com>\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.freedesktop.gstreamer.Buffer;\nimport org.freedesktop.gstreamer.lowlevel.GstMiniObjectAPI.MiniObjectStruct;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\n\nimport com.sun.jna.NativeLong;\nimport com.sun.jna.Pointer;\nimport com.sun.jna.ptr.PointerByReference;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstAPI.GST_PADDING;\n\n/**\n * GstBuffer methods and structures\n * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/gst/gstbuffer.h?h=1.8\n */\npublic interface GstBufferAPI extends com.sun.jna.Library {\n    \n    GstBufferAPI GSTBUFFER_API = GstNative.load(GstBufferAPI.class);\n\n    public static final int GST_LOCK_FLAG_READ = (1 << 0);\n    public static final int GST_LOCK_FLAG_WRITE = (1 << 1);\n    public static final int GST_MAP_READ = GST_LOCK_FLAG_READ;\n    public static final int GST_MAP_WRITE = GST_LOCK_FLAG_WRITE;\n    \n    /**\n    * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/gst/gstmemory.h?h=1.8\n    * \n    * GstMapInfo:\n    * @memory: a pointer to the mapped memory\n    * @flags: flags used when mapping the memory\n    * @data: (array length=size): a pointer to the mapped data\n    * @size: the valid size in @data\n    * @maxsize: the maximum bytes in @data\n    * @user_data: extra private user_data that the implementation of the memory\n    *             can use to store extra info.\n    *\n    * A structure containing the result of a map operation such as\n    * gst_memory_map(). It contains the data and size.\n    */\n    public static final class MapInfoStruct extends com.sun.jna.Structure {\n    \tpublic volatile Pointer memory; // Pointer to GstMemory\n    \tpublic volatile int flags; // GstMapFlags\n        public volatile Pointer /* gunit8 */ data;\n        public volatile NativeLong size;\n        public volatile NativeLong maxSize;\n        \n        /*< protected >*/\n        public volatile Pointer[] user_data = new Pointer[4];\n        \n        /*< private >*/\n        public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING];\n        \n        /**\n         * Creates a new instance of MessageStruct\n         */\n        public MapInfoStruct() {\n        }\n        public MapInfoStruct(Pointer ptr) {\n            super(ptr);\n        }\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"memory\", \"flags\", \"data\", \"size\", \"maxSize\",\n                \"user_data\", \"_gst_reserved\"\n            });\n        }\n    }\n    \n    GType gst_buffer_get_type();\n    \n    /* allocation */\n    @CallerOwnsReturn Buffer gst_buffer_new();\n    @CallerOwnsReturn Buffer gst_buffer_new_allocate(Pointer allocator, int size, Pointer params);\n    @CallerOwnsReturn Pointer ptr_gst_buffer_new();\n    @CallerOwnsReturn Pointer ptr_gst_buffer_new_allocate(Pointer allocator, int size, Pointer params);\n    \n    /* memory blocks */\n    NativeLong gst_buffer_get_size(Buffer buffer);\n    boolean gst_buffer_map(Buffer buffer, MapInfoStruct info, int flags);\n    void gst_buffer_unmap(Buffer buffer, MapInfoStruct info);\n    int gst_buffer_n_memory(Buffer buffer);\n    boolean gst_buffer_map_range(Buffer buffer, int idx, int length, MapInfoStruct info, int flags);\n    GstMetaPtr gst_buffer_get_meta(Buffer buffer, GType gType);\n    int gst_buffer_get_n_meta(Buffer buffer,GType gType);\n    GstMetaPtr gst_buffer_iterate_meta(Buffer buffer, PointerByReference state);\n    // re-introduces in gstreamer 1.9\n    int gst_buffer_get_flags(Buffer buffer);\n    boolean gst_buffer_set_flags(Buffer buffer, int flags);\n    boolean gst_buffer_unset_flags(Buffer buffer, int flags);\n    \n//    boolean gst_buffer_is_metadata_writable(Buffer buf);\n//    Buffer gst_buffer_make_metadata_writable(@Invalidate Buffer buf);\n//    /* creating a subbuffer */\n//    @CallerOwnsReturn Buffer gst_buffer_create_sub(Buffer parent, int offset, int size);\n//    \n//    @CallerOwnsReturn Caps gst_buffer_get_caps(Buffer buffer);\n//    void gst_buffer_set_caps(Buffer buffer, Caps caps);\n//    /* span two buffers intelligently */\n//    boolean gst_buffer_is_span_fast(Buffer buf1, Buffer buf2);\n//    @CallerOwnsReturn Buffer gst_buffer_span(Buffer buf1, int offset, Buffer buf2, int len);\n//    /* buffer functions from gstutils.h */\n//    @CallerOwnsReturn Buffer gst_buffer_merge(Buffer buf1, Buffer buf2);\n//    @CallerOwnsReturn Buffer gst_buffer_join(@Invalidate Buffer buf1, @Invalidate Buffer buf2);\n    \n    /**\n    * GstBuffer:\n    * @mini_object: the parent structure\n    * @pool: pointer to the pool owner of the buffer\n    * @pts: presentation timestamp of the buffer, can be #GST_CLOCK_TIME_NONE when the\n    *     pts is not known or relevant. The pts contains the timestamp when the\n    *     media should be presented to the user.\n    * @dts: decoding timestamp of the buffer, can be #GST_CLOCK_TIME_NONE when the\n    *     dts is not known or relevant. The dts contains the timestamp when the\n    *     media should be processed.\n    * @duration: duration in time of the buffer data, can be #GST_CLOCK_TIME_NONE\n    *     when the duration is not known or relevant.\n    * @offset: a media specific offset for the buffer data.\n    *     For video frames, this is the frame number of this buffer.\n    *     For audio samples, this is the offset of the first sample in this buffer.\n    *     For file data or compressed data this is the byte offset of the first\n    *       byte in this buffer.\n    * @offset_end: the last offset contained in this buffer. It has the same\n    *     format as @offset.\n    *\n    * The structure of a #GstBuffer. Use the associated macros to access the public\n    * variables.\n    */\n    public static final class BufferStruct extends com.sun.jna.Structure {\n        volatile public MiniObjectStruct mini_object;\n        \n        /*< public >*/ /* with COW */\n        public Pointer /* BufferPool */ pool;\n        \n        /* timestamp */\n        public long pts;\n        public long dts;\n        public long duration;\n        \n        /* media specific offset */\n        public long offset;\n        public long offset_end;\n        \n        public BufferStruct(Pointer ptr) {\n            super(ptr);\n        }\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"mini_object\", \"pool\", \"pts\",\n                \"dts\", \"duration\",\n                \"offset\", \"offset_end\"\n            });\n        }\n        \n        @Override\n        public String toString() {\n        \treturn super.toString() + \" \" + pts + \" \" + dts + \" \" + duration;\n        }\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstBufferPoolAPI.java",
    "content": "/*\n * Copyright (c) 2016 Christophe Lafolet\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.BufferPool;\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.Structure;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\n\nimport com.sun.jna.Pointer;\n\n/**\n * GstBufferPool methods and structures\n * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/gst/gstbufferpool.h?h=1.8\n */\npublic interface GstBufferPoolAPI extends com.sun.jna.Library {\n    GstBufferPoolAPI GSTBUFFERPOOL_API = GstNative.load(GstBufferPoolAPI.class);\n\n    GType gst_buffer_pool_get_type();\n\n    /* allocation */\n    @CallerOwnsReturn BufferPool gst_buffer_pool_new();    \n    Pointer ptr_gst_buffer_pool_new();\n    \n    /* state management */\n    Structure gst_buffer_pool_get_config(BufferPool pool);\n    \n    /* helpers for configuring the config structure */\n    boolean gst_buffer_pool_config_get_params(Structure config, /* Caps ** */ Pointer[] caps, /* guint * */ int[] size, /* guint * */ int[] min_buffers, /* guint * */ int[] max_buffers);\n    void gst_buffer_pool_config_set_params(Structure config, Caps caps, int size, int min_buffers, int max_buffers);\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstBusAPI.java",
    "content": "/* \n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2014 Tom Greenwood <tgreenwood@cafex.com>\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.Bus;\nimport org.freedesktop.gstreamer.BusSyncReply;\nimport org.freedesktop.gstreamer.message.Message;\nimport org.freedesktop.gstreamer.message.MessageType;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI.GDestroyNotify;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\nimport org.freedesktop.gstreamer.lowlevel.annotations.IncRef;\n\nimport com.sun.jna.NativeLong;\nimport com.sun.jna.Pointer;\n\n/**\n * GstBus functions\n */\npublic interface GstBusAPI extends com.sun.jna.Library {\n    GstBusAPI GSTBUS_API = GstNative.load(GstBusAPI.class);\n\n//    GType gst_bus_get_type(); - Unused\n    Bus gst_bus_new();\n    boolean gst_bus_post(Bus bus, @IncRef Message message);\n\n    boolean gst_bus_have_pending(Bus bus);\n    @CallerOwnsReturn Message gst_bus_peek(Bus bus);\n    @CallerOwnsReturn Message gst_bus_pop(Bus bus);\n    @CallerOwnsReturn Message gst_bus_pop_filtered(Bus bus, MessageType types);\n    @CallerOwnsReturn Message gst_bus_timed_pop(Bus bus, long timeout);\n    @CallerOwnsReturn Message gst_bus_timed_pop_filtered(Bus bus, long timeout, MessageType types);\n    /* polling the bus */\n    @CallerOwnsReturn Message gst_bus_poll(Bus bus, MessageType events, /* GstlongDiff */ long timeout);\n//    @CallerOwnsReturn Message gst_bus_poll(Bus bus, MessageType events, long timeout);\n\n    void gst_bus_set_flushing(Bus ptr, int flushing);\n    interface BusCallback extends GstCallback {\n        boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer data);\n    }\n    public interface BusSyncHandler extends GstCallback {\n    \tBusSyncReply callback(GstBusPtr bus, GstMessagePtr msg, Pointer userData);\n    }\n    NativeLong gst_bus_add_watch(Bus bus, BusCallback function, Pointer data);\n    void gst_bus_set_sync_handler(Bus bus, BusSyncHandler function, Pointer data, GDestroyNotify destroyCallback);\n    void gst_bus_enable_sync_message_emission(Bus bus);\n    void gst_bus_disable_sync_message_emission(Bus bus);\n    \n    void gst_bus_add_signal_watch(Bus bus);\n    void gst_bus_remove_signal_watch(Bus bus);\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstBusPtr.java",
    "content": "/*\n * Copyright (c) 2020 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Pointer;\n\n/**\n * GstBus pointer.\n */\npublic class GstBusPtr extends GstObjectPtr {\n    \n    public GstBusPtr() {\n    }\n    \n    public GstBusPtr(Pointer ptr) {\n        super(ptr);\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstCapsAPI.java",
    "content": "/* \n * Copyright (c) 2015 Neil C Smith \n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.Structure;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\nimport org.freedesktop.gstreamer.lowlevel.annotations.FreeReturnValue;\nimport org.freedesktop.gstreamer.lowlevel.annotations.Invalidate;\n\nimport com.sun.jna.Pointer;\n\n/**\n * GstCaps functions\n */\npublic interface GstCapsAPI extends com.sun.jna.Library {\n    GstCapsAPI GSTCAPS_API = GstNative.load(GstCapsAPI.class);\n\n    GType gst_caps_get_type();\n    @CallerOwnsReturn Pointer ptr_gst_caps_new_empty();\n    @CallerOwnsReturn Pointer ptr_gst_caps_new_any();\n    @CallerOwnsReturn Pointer ptr_gst_caps_new_simple(String media_type, String fieldName, Object... args);\n    @CallerOwnsReturn Pointer ptr_gst_caps_new_full(Structure... data);\n    @CallerOwnsReturn Caps gst_caps_new_empty();\n    @CallerOwnsReturn Caps gst_caps_new_any();\n    @CallerOwnsReturn Caps gst_caps_new_simple(String media_type, String fieldName, Object... args);\n    @CallerOwnsReturn Caps gst_caps_new_full(Structure... data);\n    \n    @CallerOwnsReturn Pointer ptr_gst_caps_copy(Caps caps);\n    @CallerOwnsReturn Pointer ptr_gst_caps_from_string(String string);\n    @CallerOwnsReturn Caps gst_caps_copy(Caps caps);\n    @CallerOwnsReturn Caps gst_caps_from_string(String string);\n    \n    @CallerOwnsReturn Caps gst_caps_make_writable(@Invalidate Caps caps);\n    \n    /* manipulation */\n    void gst_caps_append(Caps caps1, @Invalidate Caps caps2);\n    @CallerOwnsReturn Caps gst_caps_merge(@Invalidate Caps caps1, @Invalidate Caps caps2);\n    void gst_caps_append_structure(Caps caps, @Invalidate Structure structure);\n    void gst_caps_remove_structure(Caps caps, int idx);\n    void gst_caps_merge_structure(Caps caps, @Invalidate Structure structure);\n    int gst_caps_get_size(Caps caps);\n    Structure gst_caps_get_structure(Caps caps, int index);\n    @CallerOwnsReturn Structure gst_caps_steal_structure(Caps caps, int index);\n    @CallerOwnsReturn Caps gst_caps_copy_nth(Caps caps, int nth);\n    @CallerOwnsReturn Caps gst_caps_truncate(Caps caps);\n    void gst_caps_set_simple(Caps caps, String field, Object... values);\n    /* operations */\n    @CallerOwnsReturn Caps gst_caps_intersect( Caps caps1,  Caps caps2);\n    @CallerOwnsReturn Caps gst_caps_subtract( Caps minuend,  Caps subtrahend);\n    @CallerOwnsReturn Caps gst_caps_normalize( Caps caps);\n    @CallerOwnsReturn Caps gst_caps_simplify(Caps caps);\n    @FreeReturnValue String gst_caps_to_string(Caps caps);\n    /* tests */\n\n    boolean gst_caps_is_any(Caps caps);\n    boolean gst_caps_is_empty(Caps caps);\n    boolean gst_caps_is_fixed(Caps caps);\n    boolean gst_caps_is_always_compatible(Caps caps1,  Caps caps2);\n    boolean gst_caps_is_subset(Caps subset,  Caps superset);\n    boolean gst_caps_is_equal(Caps caps1,  Caps caps2);\n    boolean gst_caps_is_equal_fixed(Caps caps1,  Caps caps2);\n    boolean gst_caps_can_intersect(Caps caps1, Caps caps2);\n   \n    GType gst_static_caps_get_type();\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstClockAPI.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.Clock;\nimport org.freedesktop.gstreamer.ClockID;\nimport org.freedesktop.gstreamer.ClockReturn;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\n\nimport com.sun.jna.Pointer;\n\n\n/**\n * GstClock functions\n */\npublic interface GstClockAPI extends com.sun.jna.Library {\n    GstClockAPI GSTCLOCK_API = GstNative.load(GstClockAPI.class);\n\n    GType gst_clock_get_type();\n    long gst_clock_set_resolution(Clock clock, long resolution);\n    long gst_clock_get_resolution(Clock clock);\n    long gst_clock_get_time(Clock clock);\n    void gst_clock_set_calibration(Clock clock, long internal, long external, long rate_num, long rate_denom);\n    void gst_clock_get_calibration(Clock clock, long[] internal, long[] external,\n            long[] rate_num, long[] rate_denom);\n    /* master/slave clocks */\n    boolean gst_clock_set_master(Clock clock, Clock master);\n    @CallerOwnsReturn Clock gst_clock_get_master(Clock clock);\n    boolean gst_clock_add_observation(Clock clock, long slave, long Master, double[] r_squared);\n    \n    /* getting and adjusting internal time */\n    long gst_clock_get_internal_time(Clock clock);\n    long gst_clock_adjust_unlocked(Clock clock, long internal);\n    long gst_clock_unadjust_unlocked(Clock clock, long external);\n\n\n    /* creating IDs that can be used to get notifications */\n    @CallerOwnsReturn ClockID gst_clock_new_single_shot_id(Clock clock, long time);\n    @CallerOwnsReturn ClockID gst_clock_new_periodic_id(Clock clock, long start_time, long interval);\n\n    \n    /* reference counting */\n    void gst_clock_id_ref(ClockID id);\n    void gst_clock_id_ref(GPointer id);\n    void gst_clock_id_unref(ClockID id);\n    void gst_clock_id_unref(GPointer id);\n\n    /* operations on IDs */\n    int gst_clock_id_compare_func(ClockID id1, ClockID id2);\n\n    long gst_clock_id_get_time(ClockID id);\n    ClockReturn gst_clock_id_wait(ClockID id, /* GstlongDiff * */ long[] jitter);\n    public static interface GstClockCallback {\n        /**\n         * @param clock The clock that triggered the callback\n         * @param time The time it was triggered\n         * @param id The {@link ClockID} that expired\n         * @return currently unused.\n         */\n        boolean callback(Clock clock, long time, ClockID id, Pointer user_data);\n    }\n\n    ClockReturn gst_clock_id_wait_async(ClockID id, GstClockCallback func, Pointer user_data);\n    void gst_clock_id_unschedule(ClockID id);\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstColorBalanceAPI.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2009 Tamas Korodi <kotyo@zamba.fm>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.interfaces.ColorBalance;\nimport org.freedesktop.gstreamer.interfaces.ColorBalanceChannel;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI.GList;\n\nimport com.sun.jna.Library;\nimport com.sun.jna.Pointer;\nimport java.util.Arrays;\nimport java.util.List;\n\npublic interface GstColorBalanceAPI extends Library {\n\tGstColorBalanceAPI GSTCOLORBALANCE_API = GstNative.load(\"gstvideo\", GstColorBalanceAPI.class);\n\n\tGType gst_color_balance_channel_get_type();\n\tGType gst_color_balance_get_type();\n\n\t/* vitrual class functions */\n\tGList gst_color_balance_list_channels(ColorBalance balance);\n\n\tvoid gst_color_balance_set_value(ColorBalance balance, ColorBalanceChannel channel, int value);\n\n\tint gst_color_balance_get_value(ColorBalance balance, ColorBalanceChannel channel);\n\n\tpublic static final class ColorBalanceChannelStruct extends com.sun.jna.Structure {\n\t\tpublic volatile GObjectAPI.GObjectStruct parent;\n\t\tpublic volatile String label;\n\t\tpublic volatile int min_value;\n\t\tpublic volatile int max_value;\n\n\t\tpublic String getLabel() {\n\t\t\treturn (String) readField(\"label\");\n\t\t}\n\t\tpublic int getMinValue() {\n\t\t\treturn (Integer) readField(\"min_value\");\n\t\t}\n\t\tpublic int getMaxValue() {\n\t\t\treturn (Integer) readField(\"max_value\");\n\t\t}\n\t\tpublic void read() {}\n\t\tpublic void write() {}\n\t\tpublic ColorBalanceChannelStruct(Pointer ptr) {\n\t\t\tuseMemory(ptr);\n\t\t}\n\n                @Override\n                protected List<String> getFieldOrder() {\n                    return Arrays.asList(new String[]{\n                        \"parent\", \"label\", \"min_value\",\n                        \"max_value\"\n                    });\n                }\n\t}\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstContextAPI.java",
    "content": "package org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.Structure;\n\n/**\n * GstContext API\n * \n * https://gstreamer.freedesktop.org/documentation/gstreamer/gstcontext.html\n * \n * https://gitlab.freedesktop.org/gstreamer/gstreamer/blob/master/gst/gstcontext.h\n * https://gitlab.freedesktop.org/gstreamer/gstreamer/blob/master/gst/gstcontext.c\n */\npublic interface GstContextAPI extends com.sun.jna.Library {\n\n    GstContextAPI GSTCONTEXT_API = GstNative.load(GstContextAPI.class);\n\n    /*@CallerOwnsReturn*/ GstContextPtr gst_context_new(String context_type, boolean persistent);\n\n    String gst_context_get_context_type(GstContextPtr context);\n\n    boolean gst_context_has_context_type(GstContextPtr context, String context_type);\n\n    Structure gst_context_get_structure(GstContextPtr context);\n\n    Structure gst_context_writable_structure(GstContextPtr context);\n\n    boolean gst_context_is_persistent(GstContextPtr context);\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstContextPtr.java",
    "content": "package org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Pointer;\n\npublic class GstContextPtr extends GstMiniObjectPtr {\n\n    public GstContextPtr() {\n    }\n\n    public GstContextPtr(Pointer ptr) {\n        super(ptr);\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstControlBindingAPI.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Library;\n\n/**\n * GstControlBinding API\n * \n * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstControlBinding.html\n * https://gitlab.freedesktop.org/gstreamer/gstreamer/tree/master/libs/gst/controller\n */\n\npublic interface GstControlBindingAPI extends Library {\n\n    GstControlBindingAPI GSTCONTROLBINDING_API = GstNative.load(GstControlBindingAPI.class);    \n\n\n    boolean gst_control_binding_sync_values(GstControlBindingPtr binding,\n            GstObjectPtr object,\n            long timestamp,\n            long lastSync);\n    \n    GValueAPI.GValue gst_control_binding_get_value(GstControlBindingPtr binding,\n            long timestamp);\n    \n    boolean gst_control_binding_get_g_value_array(GstControlBindingPtr binding,\n            long timestamp,\n            long internal,\n            int n_values,\n            GValueAPI.GValue[] values);\n    \n    void gst_control_binding_set_disabled(GstControlBindingPtr binding,\n            boolean disabled);\n    \n    boolean gst_control_binding_is_disabled(GstControlBindingPtr binding);\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstControlBindingPtr.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Pointer;\n\n/**\n * \n */\npublic class GstControlBindingPtr extends GstObjectPtr {\n    \n    public GstControlBindingPtr() {\n    }\n    \n    public GstControlBindingPtr(Pointer ptr) {\n        super(ptr);\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstControlSourceAPI.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Library;\nimport com.sun.jna.Pointer;\nimport com.sun.jna.Structure;\n\n/**\n * GstControlSource API\n *\n * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstControlBinding.html\n * https://gitlab.freedesktop.org/gstreamer/gstreamer/tree/master/libs/gst/controller\n */\n\npublic interface GstControlSourceAPI extends Library {\n\n    GstControlSourceAPI GSTCONTROLSOURCE_API = GstNative.load(GstControlSourceAPI.class);    \n\n\n    boolean gst_control_source_get_value(GstControlSourcePtr self, long timestamp, double[] value);\n    boolean gst_control_source_get_value_array(GstControlSourcePtr self, long timestamp, long interval, int n_values, double[] values);\n\n//    static class Direct implements GstControlSourceAPI {\n//\n//        @Override\n//        public native boolean gst_control_source_get_value(GstControlSourcePtr self, long timestamp, double[] value);\n//\n//        @Override\n//        public native boolean gst_control_source_get_value_array(GstControlSourcePtr self, long timestamp, long interval, int n_values, double[] values);\n//        \n//    }\n\n    @Structure.FieldOrder({\"timestamp\", \"value\"})\n    public static final class GstTimedValue extends Structure {\n        \n        public volatile long timestamp;\n        public volatile double value;\n        \n        public GstTimedValue() {\n            super();\n        }\n        \n        public GstTimedValue(Pointer ptr) {\n            super(ptr);\n        }\n        \n    } \n    \n    \n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstControlSourcePtr.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Pointer;\n\n/**\n * \n */\npublic class GstControlSourcePtr extends GstObjectPtr {\n    \n    public GstControlSourcePtr() {\n    }\n    \n    public GstControlSourcePtr(Pointer ptr) {\n        super(ptr);\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstControllerAPI.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Library;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\n\n/**\n * GstController API functions\n * \n * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstTimedValueControlSource.html\n * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstInterpolationControlSource.html\n * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstLFOControlSource.html\n * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstTriggerControlSource.html\n * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstDirectControlBinding.html\n * \n */\npublic interface GstControllerAPI extends Library {\n    \n    GstControllerAPI GSTCONTROLLER_API = GstNative.load(\"gstcontroller\", GstControllerAPI.class);\n    \n    @CallerOwnsReturn GstTriggerControlSourcePtr gst_trigger_control_source_new();\n    \n    @CallerOwnsReturn GstInterpolationControlSourcePtr gst_interpolation_control_source_new();\n    \n    @CallerOwnsReturn GstLFOControlSourcePtr gst_lfo_control_source_new();\n    \n    @CallerOwnsReturn GstDirectControlBindingPtr gst_direct_control_binding_new(\n            GstObjectPtr object,\n            String property_name,\n            GstControlSourcePtr cs);\n    \n    @CallerOwnsReturn GstDirectControlBindingPtr gst_direct_control_binding_new_absolute(\n            GstObjectPtr object,\n            String property_name,\n            GstControlSourcePtr cs);\n    \n    @CallerOwnsReturn GstARGBControlBindingPtr gst_argb_control_binding_new(\n            GstObjectPtr object,\n            String property_name,\n            GstControlSourcePtr cs_a,\n            GstControlSourcePtr cs_r,\n            GstControlSourcePtr cs_g,\n            GstControlSourcePtr cs_b);\n    \n    // since 1.12\n    @CallerOwnsReturn GstProxyControlBindingPtr gst_proxy_control_binding_new(\n            GstObjectPtr object,\n            String property_name,\n            GstObjectPtr ref_object,\n            String ref_property_name); \n            \n    \n    // GSequenceIter gst_timed_value_control_source_find_control_point_iter(\n    //                        GstTimedValueControlSourcePtr self,\n    //                        long timestamp);\n    \n    boolean gst_timed_value_control_source_set(GstTimedValueControlSourcePtr self,\n            long timestamp,\n            double value);\n    \n    boolean gst_timed_value_control_source_set_from_list(\n                GstTimedValueControlSourcePtr self,\n                GlibAPI.GSList timedvalues);\n\n    // transfer container\n    // caller owns list, not contained values!\n    @CallerOwnsReturn GlibAPI.GList gst_timed_value_control_source_get_all(\n            GstTimedValueControlSourcePtr self);\n    \n    boolean gst_timed_value_control_source_unset(GstTimedValueControlSourcePtr self,\n            long timestamp);\n    \n    void gst_timed_value_control_source_unset_all(GstTimedValueControlSourcePtr self);\n    \n    int gst_timed_value_control_source_get_count(GstTimedValueControlSourcePtr self);\n    \n    void gst_timed_value_control_invalidate_cache(GstTimedValueControlSourcePtr self);\n    \n    // gst_control_point_copy\n    // gst_control_point_free\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstDateTimeAPI.java",
    "content": "/* \n * Copyright (c) 2010 Levente Farkas\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\n\nimport com.sun.jna.Pointer;\n\n\n/**\n * GstDateTime functions\n * \n * A date, time and timezone structure\n *\n * Struct to store date, time and timezone information altogether.\n * GstDateTime is refcounted and immutable.\n *\n * Date information is handled using the proleptic Gregorian calendar.\n *\n * Provides basic creation functions and accessor functions to its fields.\n */\npublic interface GstDateTimeAPI extends com.sun.jna.Library {\n\tGstDateTimeAPI GSTDATETIME_API = GstNative.load(GstDateTimeAPI.class);\n\n\tGType\tgst_date_time_get_type();\n\tint\tgst_date_time_get_year(Pointer datetime);\n\tint\tgst_date_time_get_month(Pointer datetime);\n\tint\tgst_date_time_get_day(Pointer datetime);\n\tint\tgst_date_time_get_hour(Pointer datetime);\n\tint\tgst_date_time_get_minute(Pointer datetime);\n\tint\tgst_date_time_get_second(Pointer datetime);\n\tint\tgst_date_time_get_microsecond(Pointer datetime);\n\tfloat gst_date_time_get_time_zone_offset(Pointer datetime);\n\n\t@CallerOwnsReturn Pointer gst_date_time_new_from_unix_epoch_local_time(long secs);\n\t@CallerOwnsReturn Pointer gst_date_time_new_from_unix_epoch_utc(long secs);\n\t@CallerOwnsReturn Pointer gst_date_time_new_local_time(int year, \n\t\t\tint month, int day, int hour, int minute, double seconds);\n\t@CallerOwnsReturn Pointer gst_date_time_new(float tzoffset, int year, \n\t\t\tint month, int day, int hour, int minute, double seconds);\n\t@CallerOwnsReturn Pointer gst_date_time_new_now_local_time();\n\t@CallerOwnsReturn Pointer gst_date_time_new_now_utc();\n\n\tPointer gst_date_time_ref(Pointer datetime);\n\tvoid gst_date_time_unref(Pointer datetime);\t\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstDeviceAPI.java",
    "content": "/*\n * Copyright (c) 2017 Neil C Smith\n * Copyright (c) 2015 Andres Colubri <andres.colubri@gmail.com>\n * Copyright (C) 2013 Olivier Crete <olivier.crete@collabora.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.Element;\nimport org.freedesktop.gstreamer.Structure;\nimport org.freedesktop.gstreamer.device.Device;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\n\n/**\n *\n * http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstDevice.html\n */ \npublic interface GstDeviceAPI extends com.sun.jna.Library {\n    GstDeviceAPI GSTDEVICE_API = GstNative.load(GstDeviceAPI.class);\n    \n    @CallerOwnsReturn Element gst_device_create_element(Device device, String name);\n    @CallerOwnsReturn Caps gst_device_get_caps(Device device);\n    Pointer gst_device_get_device_class(Device device);\n    Pointer gst_device_get_display_name(Device device);\n    boolean gst_device_has_classes(Device device, String classes);\n    boolean gst_device_has_classesv(Device device, String[] classes);\n    boolean gst_device_reconfigure_element(Device device, Element element);\n    Structure gst_device_get_properties(Device device);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstDeviceMonitorAPI.java",
    "content": "/*\n * Copyright (c) 2015 Andres Colubri <andres.colubri@gmail.com>\n*  Copyright (C) 2013 Olivier Crete <olivier.crete@collabora.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.Bus;\nimport org.freedesktop.gstreamer.device.DeviceMonitor;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI.GList;\nimport org.freedesktop.gstreamer.Caps;\n\n/**\n *\n * http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstDeviceMonitor.html\n */ \npublic interface GstDeviceMonitorAPI extends com.sun.jna.Library {\n    GstDeviceMonitorAPI GSTDEVICEMONITOR_API = GstNative.load(GstDeviceMonitorAPI.class);\n    \n    @CallerOwnsReturn DeviceMonitor gst_device_monitor_new();\n    @CallerOwnsReturn Pointer ptr_gst_device_monitor_new();\n    @CallerOwnsReturn Bus gst_device_monitor_get_bus(DeviceMonitor monitor);\n    int gst_device_monitor_add_filter(DeviceMonitor monitor, String classes, Caps caps);\n    boolean gst_device_monitor_remove_filter(DeviceMonitor monitor, int filterId);\n    boolean gst_device_monitor_start(DeviceMonitor monitor);\n    void gst_device_monitor_stop(DeviceMonitor monitor);\n    GList gst_device_monitor_get_devices(DeviceMonitor monitor);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstDeviceProviderAPI.java",
    "content": "/*\n * Copyright (c) 2015 Andres Colubri <andres.colubri@gmail.com>\n*  Copyright (C) 2013 Olivier Crete <olivier.crete@collabora.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Pointer;\nimport java.util.Arrays;\nimport java.util.List;\nimport org.freedesktop.gstreamer.Bus;\nimport org.freedesktop.gstreamer.Plugin;\nimport org.freedesktop.gstreamer.device.Device;\nimport org.freedesktop.gstreamer.device.DeviceProvider;\nimport org.freedesktop.gstreamer.device.DeviceProviderFactory;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI.GList;\n\n/**\n *\n * http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstDeviceProvider.html\n */\npublic interface GstDeviceProviderAPI extends com.sun.jna.Library {\n    GstDeviceProviderAPI GSTDEVICEPROVIDER_API = GstNative.load(GstDeviceProviderAPI.class);\n    \n    boolean gst_device_provider_can_monitor(DeviceProvider provider);\n    void gst_device_provider_class_add_metadata(GstDeviceProviderClass klass,\n                                                String key, String value);    \n    void gst_device_provider_class_add_static_metadata(GstDeviceProviderClass klass,\n                                                       String key, String  value);\n    String gst_device_provider_class_get_metadata(GstDeviceProviderClass klass, String key);\n    void gst_device_provider_class_set_metadata(GstDeviceProviderClass klass,\n                                                String longname, String classification, String description, String author);\n    void gst_device_provider_class_set_static_metadata(GstDeviceProviderClass klass,\n                                                       String longname, String classification, String description, String author);\n    void gst_device_provider_device_add(DeviceProvider provider, Device device);\n    void gst_device_provider_device_remove(DeviceProvider provider, Device device);\n    Bus gst_device_provider_get_bus(DeviceProvider provider);\n    GList gst_device_provider_get_devices(DeviceProvider provider);\n    DeviceProviderFactory gst_device_provider_get_factory(DeviceProvider provider);\n    boolean gst_device_provider_register(Plugin plugin, String name, int rank, GType type);\n    boolean gst_device_provider_start(DeviceProvider provider);\n    void gst_device_provider_stop(DeviceProvider provider);\n        \n    public static final class GstDeviceProviderClass extends com.sun.jna.Structure {\n        public GObjectAPI.GObjectClass parent_class;\n        public volatile Pointer factory;\n        public volatile Pointer probe;\n        public volatile Pointer start;\n        public volatile Pointer provider;        \n        public volatile Pointer metadata;\n        public volatile Pointer[] _gst_reserved = new Pointer[GstAPI.GST_PADDING];        \n        \n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"parent_class\", \"factory\",\n                \"probe\", \"start\", \"provider\",\n                \"metadata\", \"_gst_reserved\"\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstDeviceProviderFactoryAPI.java",
    "content": "/*\n * Copyright (c) 2015 Andres Colubri <andres.colubri@gmail.com>\n*  Copyright (C) 2013 Olivier Crete <olivier.crete@collabora.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.PluginFeature.Rank;\nimport org.freedesktop.gstreamer.device.DeviceProvider;\nimport org.freedesktop.gstreamer.device.DeviceProviderFactory;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI.GList;\n\n/**\n *\n * http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstDeviceProviderFactory.html\n */\npublic interface GstDeviceProviderFactoryAPI extends com.sun.jna.Library {\n    GstDeviceProviderFactoryAPI GSTDEVICEPROVIDERFACTORY_API = GstNative.load(GstDeviceProviderFactoryAPI.class);\n    \n    DeviceProviderFactory gst_device_provider_factory_find(String name);\n    DeviceProvider gst_device_provider_factory_get(DeviceProviderFactory factory);\n    DeviceProvider gst_device_provider_factory_get_by_name(String factoryName);\n    GType gst_device_provider_factory_get_device_provider_type(DeviceProviderFactory factory);\n    String gst_device_provider_factory_get_metadata(DeviceProviderFactory factory, String key);\n    String[] gst_device_provider_factory_get_metadata_keys(DeviceProviderFactory factory);    \n    boolean gst_device_provider_factory_has_classes(DeviceProviderFactory factory, String classes);\n    boolean gst_device_provider_factory_has_classesv(DeviceProviderFactory factory, String[] classes);\n    GList gst_device_provider_factory_list_get_device_providers(Rank minRank);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstDirectControlBindingPtr.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Pointer;\n\n/**\n * \n */\npublic class GstDirectControlBindingPtr extends GstControlBindingPtr {\n    \n    public GstDirectControlBindingPtr() {\n    }\n    \n    public GstDirectControlBindingPtr(Pointer ptr) {\n        super(ptr);\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstElementAPI.java",
    "content": "/* \n * Copyright (c) 2021 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\n\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.freedesktop.gstreamer.Bus;\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.Clock;\nimport org.freedesktop.gstreamer.Element;\nimport org.freedesktop.gstreamer.ElementFactory;\nimport org.freedesktop.gstreamer.event.Event;\nimport org.freedesktop.gstreamer.Format;\nimport org.freedesktop.gstreamer.message.Message;\nimport org.freedesktop.gstreamer.Pad;\nimport org.freedesktop.gstreamer.query.Query;\nimport org.freedesktop.gstreamer.event.SeekType;\nimport org.freedesktop.gstreamer.State;\nimport org.freedesktop.gstreamer.StateChangeReturn;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI.GList;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback;\nimport org.freedesktop.gstreamer.lowlevel.GstObjectAPI.GstObjectClass;\nimport org.freedesktop.gstreamer.lowlevel.GstObjectAPI.GstObjectStruct;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\nimport org.freedesktop.gstreamer.lowlevel.annotations.IncRef;\n\nimport com.sun.jna.NativeLong;\nimport com.sun.jna.Pointer;\n\n/**\n * GstElement methods and structures\n * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/gst/gstelement.h?h=1.8\n */\n\npublic interface GstElementAPI extends com.sun.jna.Library {\n    \n    GstElementAPI GSTELEMENT_API = GstNative.load(GstElementAPI.class);\n\n    GType gst_element_get_type();\n    StateChangeReturn gst_element_set_state(Element elem, State state);\n    StateChangeReturn gst_element_get_state(Element elem, State[] state, State[] pending, long timeout);\n    boolean gst_element_set_locked_state(Element element, boolean locked_state);\n    boolean gst_element_sync_state_with_parent(Element elem);\n    boolean gst_element_query_position(Element elem, Format fmt, long[] pos);\n    boolean gst_element_query_duration(Element elem, Format fmt, long[] pos);\n    boolean gst_element_query(Element elem, Query query);\n    boolean gst_element_seek(Element element, double rate, Format format, int flags,\n            SeekType start_type, long start, SeekType stop_type, long stop);\n    boolean gst_element_seek_simple(Element elem, Format format, int seek_flags, long seek_pos);\n    boolean gst_element_link(Element elem1, Element elem2);\n    boolean gst_element_link_filtered(Element elem1, Element elem2, Caps filter);\n    boolean gst_element_link_many(Element... elements);\n    void gst_element_unlink_many(Element... elements);\n    void gst_element_unlink(Element elem1, Element elem2);\n    @CallerOwnsReturn Pad gst_element_get_pad(Element elem, String name);\n    @CallerOwnsReturn Pad gst_element_get_static_pad(Element element, String name);\n    // pads returned from get_request have to be freed via release_request_pad\n    @CallerOwnsReturn Pad gst_element_get_request_pad(Element element, String name);\n    void gst_element_release_request_pad(Element element, Pad pad);\n    boolean gst_element_add_pad(Element elem, Pad pad);\n    boolean gst_element_remove_pad(Element elem, @IncRef Pad pad);\n    boolean gst_element_link_pads(Element src, String srcpadname, Element dest, String destpadname);\n    void gst_element_unlink_pads(Element src, String srcpadname, Element dest, String destpadname);\n    boolean gst_element_link_pads_filtered(Element src, String srcpadname, Element dest, String destpadname,\n            Caps filter);\n    \n    GstIteratorPtr gst_element_iterate_pads(Element element);\n    GstIteratorPtr gst_element_iterate_src_pads(Element element);\n    GstIteratorPtr gst_element_iterate_sink_pads(Element element);\n    /* factory management */\n    ElementFactory gst_element_get_factory(Element element);\n    @CallerOwnsReturn Bus gst_element_get_bus(Element element);\n    boolean gst_element_send_event(Element element, @IncRef Event event);\n    boolean gst_element_post_message(Element element, @IncRef Message message);\n\n    boolean gst_element_implements_interface(Element element, NativeLong iface_type);\n    /* clocking */\n    Clock gst_element_get_clock(Element element);\n    boolean gst_element_set_clock(Element element, Clock clock);\n    void gst_element_set_base_time(Element element, long time);\n    long gst_element_get_base_time(Element element);\n    void gst_element_set_start_time(Element element, long time);\n    long gst_element_get_start_time(Element element);\n    /* context */\n    void gst_element_set_context(Element element, GstContextPtr context);\n    GList gst_element_get_contexts(Element element);\n    @CallerOwnsReturn GstContextPtr gst_element_get_context(Element element, String context_type);\n    @CallerOwnsReturn GstContextPtr gst_element_get_context_unlocked(Element element, String context_type);\n    \n    /**\n    * GstElement:\n    * @state_lock: Used to serialize execution of gst_element_set_state()\n    * @state_cond: Used to signal completion of a state change\n    * @state_cookie: Used to detect concurrent execution of\n    * gst_element_set_state() and gst_element_get_state()\n    * @target_state: the target state of an element as set by the application\n    * @current_state: the current state of an element\n    * @next_state: the next state of an element, can be #GST_STATE_VOID_PENDING if\n    * the element is in the correct state.\n    * @pending_state: the final state the element should go to, can be\n    * #GST_STATE_VOID_PENDING if the element is in the correct state\n    * @last_return: the last return value of an element state change\n    * @bus: the bus of the element. This bus is provided to the element by the\n    * parent element or the application. A #GstPipeline has a bus of its own.\n    * @clock: the clock of the element. This clock is usually provided to the\n    * element by the toplevel #GstPipeline.\n    * @base_time: the time of the clock right before the element is set to\n    * PLAYING. Subtracting @base_time from the current clock time in the PLAYING\n    * state will yield the running_time against the clock.\n    * @start_time: the running_time of the last PAUSED state\n    * @numpads: number of pads of the element, includes both source and sink pads.\n    * @pads: (element-type Gst.Pad): list of pads\n    * @numsrcpads: number of source pads of the element.\n    * @srcpads: (element-type Gst.Pad): list of source pads\n    * @numsinkpads: number of sink pads of the element.\n    * @sinkpads: (element-type Gst.Pad): list of sink pads\n    * @pads_cookie: updated whenever the a pad is added or removed\n    *\n    * GStreamer element abstract base class.\n    */\n    public static final class GstElementStruct extends com.sun.jna.Structure {\n        public GstObjectStruct object;\n        \n        /*< public >*/ /* with LOCK */\n        public volatile Pointer /* GRecMutex */ state_lock;\n        \n        /* element state */\n        public volatile Pointer /* GCond */ state_cond;\n        public volatile int state_cookie;\n        public volatile State target_state;\n        public volatile State current_state;\n        public volatile State next_state; \n        public volatile State pending_state;         \n        public volatile StateChangeReturn last_return;\n        \n        public volatile Pointer /* GstBus */ bus;\n        \n        /* allocated clock */\n        public volatile Pointer /* GstClock */ clock;\n        public volatile long base_time;\n        public volatile long start_time;\n        \n        /* element pads, these lists can only be iterated while holding\n        * the LOCK or checking the cookie after each LOCK. */\n        public volatile short numpads;\n        public volatile Pointer /* GList */pads;\n        public volatile short numsrcpads;\n        public volatile Pointer /* GList */ srcpads;\n        public volatile short numsinkpads;\n        public volatile Pointer /* GList */sinkpads;\n        public volatile int pads_cookie;\n        \n        /* with object LOCK */\n        public volatile Pointer /* GList */contexts;\n        \n        /*< private >*/\n        public volatile Pointer[] _gst_reserved = new Pointer[GstAPI.GST_PADDING-1];\n\n        public GstElementStruct(Pointer handle) {\n            super(handle);\n        }\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"object\", \"state_lock\", \"state_cond\",\n                \"state_cookie\", \"target_state\", \"current_state\", \"next_state\",\n                \"pending_state\", \"last_return\", \"bus\",\n                \"clock\", \"base_time\", \"start_time\", \"numpads\",\n                \"pads\", \"numsrcpads\", \"srcpads\",\n                \"numsinkpads\", \"sinkpads\", \"pads_cookie\", \"contexts\",\n                \"_gst_reserved\"\n            });\n        }\n    }\n    \n    \n    /**\n    * GstElementClass:\n    * @parent_class: the parent class structure\n    * @metadata: metadata for elements of this class\n    * @elementfactory: the #GstElementFactory that creates these elements\n    * @padtemplates: a #GList of #GstPadTemplate\n    * @numpadtemplates: the number of padtemplates\n    * @pad_templ_cookie: changed whenever the padtemplates change\n    * @request_new_pad: called when a new pad is requested\n    * @release_pad: called when a request pad is to be released\n    * @get_state: get the state of the element\n    * @set_state: set a new state on the element\n    * @change_state: called by @set_state to perform an incremental state change\n    * @set_bus: set a #GstBus on the element\n    * @provide_clock: gets the #GstClock provided by the element\n    * @set_clock: set the #GstClock on the element\n    * @send_event: send a #GstEvent to the element\n    * @query: perform a #GstQuery on the element\n    * @state_changed: called immediately after a new state was set.\n    * @post_message: called when a message is posted on the element. Chain up to\n    *                the parent class' handler to have it posted on the bus.\n    * @set_context: set a #GstContext on the element\n    *\n    * GStreamer element class. Override the vmethods to implement the element\n    * functionality.\n    */\n    public static final class GstElementClass extends com.sun.jna.Structure {\n        //\n        // Callbacks for this class\n        //\n        public static interface PadAdded extends GstCallback {\n            public void callback(Element element, Pad pad);\n        }\n        public static interface PadRemoved extends GstCallback {\n            public void callback(Element element, Pad pad);\n        }\n        public static interface NoMorePads extends GstCallback {\n            public void callback(Element element);\n        }\n        public static interface RequestNewPad extends GstCallback {\n            public Pad callback(Element element, /* PadTemplate */ Pointer templ, \n                    String name, Caps caps);\n        }\n        public static interface ReleasePad extends GstCallback {\n            public void callback(Element element, Pad pad);\n        }\n        public static interface GetState extends GstCallback {\n            public StateChangeReturn callback(Element element, Pointer /* GstState */ state,\n                    Pointer /* GstState */ pending, long timeout);\n        }\n        public static interface SetState extends GstCallback {\n            public StateChangeReturn callback(Element element, State state);\n        }\n        public static interface ChangeState extends GstCallback {\n            public StateChangeReturn callback(Element element, int transition);\n        }\n        public static interface StateChanged extends GstCallback {\n            public StateChangeReturn callback(Element element, State oldState, State newState, State pending);\n        }\n        public static interface SetBus extends GstCallback {\n            public void callback(Element element, Bus bus);\n        }\n        public static interface ProvideClock extends GstCallback {\n            public void callback(Element element);\n        }\n        public static interface SetClock extends GstCallback {\n            public void callback(Element element, Clock clock);\n        }\n        public static interface SendEvent extends GstCallback {\n            boolean callback(Element element, Event event);\n        }\n        public static interface QueryNotify extends GstCallback {\n            boolean callback(Element element, Query query);\n        }\n        public static interface PostMessage extends GstCallback {\n            boolean callback(Element element, Message message);\n        }\n\n\n        //\n        // Actual data members\n        //\n        public GstObjectClass parent_class;\n        \n        /*< public >*/\n        /* the element metadata */\n        public volatile Pointer metadata;\n        \n        /* factory that the element was created from */\n        public volatile ElementFactory elementfactory;\n        \n        /* templates for our pads */\n        public volatile Pointer /* GList */ padtemplates;\n        public volatile int numpadtemplates;\n        public volatile int pad_templ_cookie;\n        \n        /*< private >*/\n        /* signal callbacks */\n        public PadAdded pad_added;\n        public PadRemoved pad_removed;\n        public NoMorePads no_more_pads;\n        \n        /* request/release pads */\n        public RequestNewPad request_new_pad;\n        public ReleasePad release_pad;\n        \n        /* state changes */\n        public GetState get_state;\n        public SetState set_state;\n        public ChangeState change_state;\n        public StateChanged state_changed;\n        \n        /* bus */\n        public volatile SetBus set_bus;\n        \n        /* set/get clocks */\n        public volatile ProvideClock provide_clock;\n        public volatile SetClock set_clock;\n\n        /* query functions */\n        public volatile SendEvent send_event;\n        public volatile QueryNotify query;\n        public volatile PostMessage post_message;\n\n        public volatile Pointer set_context;\n\n        /*< private >*/\n        // Use an array of byte if arrays of Pointer don't work\n        public volatile Pointer[] _gst_reserved = new Pointer[GstAPI.GST_PADDING_LARGE-2];\n\n        public GstElementClass(Pointer ptr) {\n            super(ptr);\n            //this.read();\n        }\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"parent_class\", \"metadata\", \"elementfactory\",\n                \"padtemplates\", \"numpadtemplates\", \"pad_templ_cookie\",\n                \"pad_added\", \"pad_removed\", \"no_more_pads\",\n                \"request_new_pad\", \"release_pad\", \"get_state\",\n                \"set_state\", \"change_state\", \"state_changed\", \"set_bus\",\n                \"provide_clock\", \"set_clock\",\n                \"send_event\", \"query\", \"post_message\",\n                \"set_context\",\n                \"_gst_reserved\"\n            });\n        }\n\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstElementFactoryAPI.java",
    "content": "/* Copyright (c) 2016 Christophe Lafolet\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.Element;\nimport org.freedesktop.gstreamer.ElementFactory;\nimport org.freedesktop.gstreamer.PadDirection;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI.GList;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\nimport org.freedesktop.gstreamer.lowlevel.annotations.Const;\n\nimport com.sun.jna.Pointer;\n\n/**\n * GstElementFactory methods\n */\npublic interface GstElementFactoryAPI extends com.sun.jna.Library {\n    GstElementFactoryAPI GSTELEMENTFACTORY_API = GstNative.load(GstElementFactoryAPI.class);\n\n    GType gst_element_factory_get_type();\n    ElementFactory gst_element_factory_find(String factoryName);\n    @CallerOwnsReturn Pointer ptr_gst_element_factory_make(String factoryName, String elementName);\n    @CallerOwnsReturn Pointer ptr_gst_element_factory_create(ElementFactory factory, String elementName);\n    @CallerOwnsReturn Element gst_element_factory_make(String factoryName, String elementName);\n    @CallerOwnsReturn Element gst_element_factory_create(ElementFactory factory, String elementName);\n    GType gst_element_factory_get_element_type(ElementFactory factory);\n    String gst_element_factory_get_metadata(ElementFactory factory, String key);\n    int gst_element_factory_get_num_pad_templates(ElementFactory factory);\n    int gst_element_factory_get_uri_type(ElementFactory factory);\n    GList gst_element_factory_get_static_pad_templates(ElementFactory factory);\n\n    GList gst_element_factory_list_get_elements(long type, int minrank);\n    GList gst_element_factory_list_filter(GList list, @Const Caps caps, PadDirection direction,\n            boolean subsetonly);\n\n    /* util elementfactory functions */\n    boolean gst_element_factory_can_src_caps(ElementFactory factory, @Const Caps caps);\n    boolean gst_element_factory_can_sink_caps(ElementFactory factory, @Const Caps caps);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstEventAPI.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.event.Event;\nimport org.freedesktop.gstreamer.event.EventType;\nimport org.freedesktop.gstreamer.Format;\nimport org.freedesktop.gstreamer.event.QOSType;\nimport org.freedesktop.gstreamer.event.SeekType;\nimport org.freedesktop.gstreamer.Structure;\nimport org.freedesktop.gstreamer.TagList;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\nimport org.freedesktop.gstreamer.lowlevel.annotations.Invalidate;\n\nimport com.sun.jna.Pointer;\nimport com.sun.jna.ptr.PointerByReference;\nimport org.freedesktop.gstreamer.lowlevel.GstMiniObjectAPI.MiniObjectStruct;\n\n/**\n * GstEvent functions and structures\n * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/gst/gstevent.h?h=1.8\n */\npublic interface GstEventAPI extends com.sun.jna.Library {\n    GstEventAPI GSTEVENT_API = GstNative.load(GstEventAPI.class);\n\n    String gst_event_type_get_name(EventType type);\n    int gst_event_type_get_flags(EventType type);\n\n    GType gst_event_get_type();\n\n    Structure gst_event_get_structure(Event event);\n\n    /* custom event */\n    Event gst_event_new_custom(EventType type, @Invalidate Structure structure);\n\n    /* flush events */\n    @CallerOwnsReturn Event gst_event_new_flush_start();\n    Pointer ptr_gst_event_new_flush_start();\n    @CallerOwnsReturn Event gst_event_new_flush_stop();\n    Pointer ptr_gst_event_new_flush_stop();\n    \n    /* EOS event */\n    @CallerOwnsReturn Event gst_event_new_eos();\n    Pointer ptr_gst_event_new_eos();\n    \n    /* newsegment events */\n    @CallerOwnsReturn Event gst_event_new_segment( GstAPI.GstSegmentStruct segmentStruct );\n    Pointer ptr_gst_event_new_segment( GstAPI.GstSegmentStruct segment);            \n    void gst_event_parse_segment(Event event, Pointer[] pointer);\n    \n    /* tag event */\n    @CallerOwnsReturn Event gst_event_new_tag(@Invalidate TagList taglist);\n    Pointer ptr_gst_event_new_tag(@Invalidate TagList taglist);\n    void gst_event_parse_tag(Event event, PointerByReference taglist);\n    void gst_event_parse_tag(Event event, Pointer[] taglist);\n    \n    /* buffer event */\n    @CallerOwnsReturn Event gst_event_new_buffer_size(Format format, long minsize, long maxsize, boolean async);\n    Pointer ptr_gst_event_new_buffer_size(Format format, long minsize, long maxsize, boolean async);\n    void gst_event_parse_buffer_size(Event event, Format[] format, long[] minsize,\n\t\t\t\t\t\t long[] maxsize, boolean[] async);\n    \n    /* QOS events */\n    @CallerOwnsReturn Event gst_event_new_qos(QOSType type, double proportion, long diff, long timestamp);\n    Pointer ptr_gst_event_new_qos(QOSType type, double proportion, long diff, long timestamp);\n    void gst_event_parse_qos(Event event, QOSType[] type, double[] proportion, long[] diff, long[] timestamp);\n    \n    /* seek event */\n    @CallerOwnsReturn Event gst_event_new_seek(double rate, Format format, int flags,\n\t\t\t\t\t\t SeekType start_type, long start,\n\t\t\t\t\t\t SeekType stop_type, long stop);\n    Pointer ptr_gst_event_new_seek(double rate, Format format, int flags,\n            SeekType start_type, long start, SeekType stop_type, long stop);\n    void gst_event_parse_seek(Event event, double[] rate, Format[] format,\n\t\t                                 int[] flags, SeekType[] start_type, long[] start,\n                                                 SeekType[] stop_type, long[] stop);\n        \n    /* navigation event */\n    @CallerOwnsReturn Event gst_event_new_navigation(@Invalidate Structure structure);\n    Pointer ptr_gst_event_new_navigation(@Invalidate Structure structure);\n\n    /* latency event */\n    @CallerOwnsReturn Event gst_event_new_latency(long latency);\n    Pointer ptr_gst_event_new_latency(long latency);\n    void gst_event_parse_latency(Event event, long[] latency);\n    \n    /* step event */\n    @CallerOwnsReturn Event gst_event_new_step(Format format, long amount, double rate, boolean flush, boolean intermediate);\n    Pointer ptr_gst_event_new_step(Format format, long amount, double rate, boolean flush, boolean intermediate);\n    \n    /* caps event */\n    @CallerOwnsReturn Event gst_event_new_caps(Caps caps);\n    Pointer ptr_gst_event_new_caps(Caps caps);\n    \n    /* reconfigure event */\n    @CallerOwnsReturn Event gst_event_new_reconfigure();\n    Pointer ptr_gst_event_new_reconfigure();\n    \n    /* stream start event */\n    @CallerOwnsReturn Event gst_event_new_stream_start(final String stream_id);\n    Pointer ptr_gst_event_new_stream_start(final String stream_id);\n    \n    /**\n    * GstEvent:\n    * @mini_object: the parent structure\n    * @type: the #GstEventType of the event\n    * @timestamp: the timestamp of the event\n    * @seqnum: the sequence number of the event\n    *\n    * A #GstEvent.\n    */\n    public static final class EventStruct extends com.sun.jna.Structure {\n        public volatile MiniObjectStruct mini_object;\n        \n        /*< public >*/ /* with COW */\n        public volatile EventType type;\n        public volatile long timestamp;\n        public volatile int seqnum;\n                \n        public EventStruct(Pointer ptr) {\n            useMemory(ptr);\n        }\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"mini_object\",\n                \"type\", \"timestamp\", \"seqnum\"\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstGhostPadAPI.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.GhostPad;\nimport org.freedesktop.gstreamer.Pad;\nimport org.freedesktop.gstreamer.PadTemplate;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\n\nimport com.sun.jna.Pointer;\n\n/**\n * GstGhostPad functions\n */\npublic interface GstGhostPadAPI extends com.sun.jna.Library {\n    GstGhostPadAPI GSTGHOSTPAD_API = GstNative.load(GstGhostPadAPI.class);\n\n    GType gst_ghost_pad_get_type();\n    \n    @CallerOwnsReturn Pointer ptr_gst_ghost_pad_new(String name, Pad target);\n    @CallerOwnsReturn Pointer ptr_gst_ghost_pad_new_no_target(String name, int direction);\n\n    @CallerOwnsReturn Pointer ptr_gst_ghost_pad_new_from_template(String name, Pad target, PadTemplate templ);\n    @CallerOwnsReturn Pointer ptr_gst_ghost_pad_new_no_target_from_template(String name, PadTemplate templ);\n    @CallerOwnsReturn GhostPad gst_ghost_pad_new(String name, Pad target);\n    @CallerOwnsReturn GhostPad gst_ghost_pad_new_no_target(String name, int direction);\n\n    @CallerOwnsReturn GhostPad gst_ghost_pad_new_from_template(String name, Pad target, PadTemplate templ);\n    @CallerOwnsReturn GhostPad gst_ghost_pad_new_no_target_from_template(String name, PadTemplate templ);\n    @CallerOwnsReturn Pad gst_ghost_pad_get_target(GhostPad gpad);\n    boolean gst_ghost_pad_set_target(GhostPad gpad, Pad newtarget);\n\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstInterpolationControlSourceAPI.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\n//import org.freedesktop.gstreamer.controller.ControlSource;\n//import org.freedesktop.gstreamer.controller.InterpolationControlSource;\nimport org.freedesktop.gstreamer.lowlevel.GValueAPI.GValue;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI.GList;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI.GSList;\n\nimport com.sun.jna.Library;\nimport com.sun.jna.Pointer;\nimport java.util.Arrays;\nimport java.util.List;\n\n// @TODO review in line with https://gitlab.freedesktop.org/gstreamer/gstreamer/blob/master/libs/gst/controller/gstinterpolationcontrolsource.h\n\npublic interface GstInterpolationControlSourceAPI extends Library {\n//\tGstInterpolationControlSourceAPI GSTINTERPOLATIONCONTROLSOURCE_API \n//\t\t= GstNative.load(\"gstcontroller\", GstInterpolationControlSourceAPI.class);\n//    int GST_PADDING = GstAPI.GST_PADDING;\n//    \n//    public enum InterpolateMode {\n//      NONE,\n//      TRIGGER,\n//      LINEAR,\n//      QUADRATIC,\n//      CUBIC,\n//      USER;\n//    }\n//\t\n//\tpublic static final class GstInterpolationControlSourceStruct extends com.sun.jna.Structure {\n//\t\tpublic volatile ControlSource parent;\n//\n//\t\t/* <private> */\n//\t\tpublic volatile Pointer /* GMutex */ lock;\n//\t\tpublic volatile Pointer /* GstInterpolationControlSourcePrivate */ priv;\n//\t\tpublic volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING];\n//\n//        @Override\n//        protected List<String> getFieldOrder() {\n//            return Arrays.asList(new String[]{\n//                \"parent\", \"lock\", \"priv\",\n//                \"_gst_reserved\"\n//            });\n//        }\n//\t}\n//\t\n//\tpublic static final class GstInterpolationControlSourceClass extends com.sun.jna.Structure {\n//\t\tpublic volatile ControlSource parent_class;\n//\t\t  \n//\t\t/*< private >*/\n//\t\tpublic volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING];\n//\n//        @Override\n//        protected List<String> getFieldOrder() {\n//            return Arrays.asList(new String[]{\n//                \"parent_class\", \"_gst_reserved\"\n//            });\n//        }\n//\t}\n//\t\n//\tGType gst_interpolation_control_source_get_type();\n//\n//\t/* Functions */\n//\tInterpolationControlSource gst_interpolation_control_source_new();\n//\tboolean gst_interpolation_control_source_set_interpolation_mode(InterpolationControlSource self, InterpolateMode mode);\n//\tboolean gst_interpolation_control_source_set(InterpolationControlSource self, long timestamp, GValue value);\n//\tboolean gst_interpolation_control_source_set_from_list(InterpolationControlSource self, GSList timedvalues);\n//\tboolean gst_interpolation_control_source_unset(InterpolationControlSource self, long timestamp);\n//\tvoid gst_interpolation_control_source_unset_all(InterpolationControlSource self);\n//\tGList gst_interpolation_control_source_get_all(InterpolationControlSource self);\n//\tint gst_interpolation_control_source_get_count(InterpolationControlSource self);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstInterpolationControlSourcePtr.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Pointer;\n\n/**\n * \n */\npublic class GstInterpolationControlSourcePtr extends GstTimedValueControlSourcePtr {\n    \n    public GstInterpolationControlSourcePtr() {\n    }\n    \n    public GstInterpolationControlSourcePtr(Pointer ptr) {\n        super(ptr);\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstIteratorAPI.java",
    "content": "/* \n * Copyright (c) 2021 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\n/**\n * GstIterator functions\n */\npublic interface GstIteratorAPI extends com.sun.jna.Library {\n    \n    GstIteratorAPI GSTITERATOR_API = GstNative.load(GstIteratorAPI.class);\n\n    void gst_iterator_free(GstIteratorPtr iter);\n    int gst_iterator_next(GstIteratorPtr iter, GValueAPI.GValue next);\n    void gst_iterator_resync(GstIteratorPtr iter);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstIteratorPtr.java",
    "content": "/*\n * Copyright (c) 2021 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Pointer;\n\n/**\n * GstIterator pointer.\n */\npublic class GstIteratorPtr extends GPointer {\n\n    public GstIteratorPtr() {\n    }\n\n    public GstIteratorPtr(Pointer ptr) {\n        super(ptr);\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstLFOControlSourcePtr.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Pointer;\n\n/**\n * \n */\npublic class GstLFOControlSourcePtr extends GstControlSourcePtr {\n    \n    public GstLFOControlSourcePtr() {\n    }\n    \n    public GstLFOControlSourcePtr(Pointer ptr) {\n        super(ptr);\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstMessageAPI.java",
    "content": "/* \n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2014 Tom Greenwood <tgreenwood@cafex.com>\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.Clock;\nimport org.freedesktop.gstreamer.Format;\nimport org.freedesktop.gstreamer.GstObject;\nimport org.freedesktop.gstreamer.message.Message;\nimport org.freedesktop.gstreamer.message.MessageType;\nimport org.freedesktop.gstreamer.State;\nimport org.freedesktop.gstreamer.Structure;\nimport org.freedesktop.gstreamer.TagList;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GErrorStruct;\nimport org.freedesktop.gstreamer.lowlevel.GstMiniObjectAPI.MiniObjectStruct;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\nimport org.freedesktop.gstreamer.lowlevel.annotations.ConstReturn;\nimport org.freedesktop.gstreamer.lowlevel.annotations.Invalidate;\n\nimport com.sun.jna.Pointer;\nimport com.sun.jna.Structure.FieldOrder;\nimport com.sun.jna.ptr.IntByReference;\nimport com.sun.jna.ptr.LongByReference;\nimport com.sun.jna.ptr.PointerByReference;\n\n/*\n * GstMessage functions\n */\npublic interface GstMessageAPI extends com.sun.jna.Library {\n    GstMessageAPI GSTMESSAGE_API = GstNative.load(GstMessageAPI.class);\n\n    @FieldOrder({\"mini_object\", \"type\", \"timestamp\", \"src\",\n        \"seqnum\", \"lock\", \"cond\"})\n    public static final class MessageStruct extends com.sun.jna.Structure {\n    \tpublic volatile MiniObjectStruct mini_object;\n        public volatile int type;\n        public volatile long timestamp;\n        public volatile GstObjectPtr src;\n        public volatile int seqnum;\n\n        public volatile Pointer lock;\n        public volatile Pointer cond;\n\n        /**\n         * Creates a new instance of MessageStruct\n         */\n        public MessageStruct() {\n        }\n        public MessageStruct(Pointer ptr) {\n            useMemory(ptr);\n        }\n        \n        int typeOffset() {\n            return fieldOffset(\"type\");\n        }\n        \n        int srcOffset() {\n            return fieldOffset(\"src\");\n        }\n    }\n    \n    GType gst_message_get_type();\n    String gst_message_type_get_name(MessageType type);\n    void gst_message_parse_state_changed(Message msg, State[] old, State[] current, State[] pending);\n    void gst_message_parse_state_changed(GstMessagePtr msg, IntByReference old, IntByReference current, IntByReference pending);\n    void gst_message_parse_tag(Message msg, PointerByReference tagList);\n    void gst_message_parse_tag(GstMessagePtr msg, PointerByReference tagList);\n    void gst_message_parse_clock_provide(Message msg, PointerByReference clock, int[] reader);\n    void gst_message_parse_new_clock(Message msg, PointerByReference clock);\n    void gst_message_parse_error(Message msg, PointerByReference err, PointerByReference debug);\n    void gst_message_parse_error(GstMessagePtr msg, PointerByReference err, PointerByReference debug);\n    void gst_message_parse_error(Message msg, GErrorStruct[] err, Pointer[] debug);\n    void gst_message_parse_warning(Message msg, PointerByReference err, PointerByReference debug);\n    void gst_message_parse_warning(GstMessagePtr msg, PointerByReference err, PointerByReference debug);\n    void gst_message_parse_warning(Message msg, GErrorStruct[] err, Pointer[] debug);\n    void gst_message_parse_info(Message msg, PointerByReference err, PointerByReference debug);\n    void gst_message_parse_info(GstMessagePtr msg, PointerByReference err, PointerByReference debug);\n    void gst_message_parse_info(Message msg, GErrorStruct[] err, Pointer[] debug);\n    void gst_message_parse_buffering(Message msg, int[] percent);\n    void gst_message_parse_buffering(GstMessagePtr msg, IntByReference percent);\n    void gst_message_parse_segment_start(Message message, Format[] format, long[] position); \n    void gst_message_parse_segment_start(GstMessagePtr msg, IntByReference format, LongByReference position); \n    void gst_message_parse_segment_done(Message message, Format[] format, long[] position);\n    void gst_message_parse_segment_done(GstMessagePtr msg, IntByReference format, LongByReference position); \n    void gst_message_parse_duration(Message message, Format[] format, long[] position);\n    void gst_message_parse_duration(GstMessagePtr msg, IntByReference format, LongByReference position);\n    void gst_message_parse_async_start(Message message, boolean[] new_base_time);\n    boolean gst_message_parse_context_type(Message message, String[] context_type);\n    boolean gst_message_parse_context_type(GstMessagePtr msg, PointerByReference /*String*/ context_type);\n    \n    @CallerOwnsReturn Message gst_message_new_eos(GstObject src);\n    Pointer ptr_gst_message_new_eos(GstObject src);\n    @CallerOwnsReturn GstMessagePtr gst_message_new_eos(GstObjectPtr src);\n    @CallerOwnsReturn Message gst_message_new_error(GstObject src, GErrorStruct error, String debug);\n    @CallerOwnsReturn Message gst_message_new_warning(GstObject src, GErrorStruct error, String debug);\n    @CallerOwnsReturn Message gst_message_new_info(GstObject src, GErrorStruct error, String debug);\n    @CallerOwnsReturn Message gst_message_new_tag(GstObject src, @Invalidate TagList tag_list);\n    Pointer ptr_gst_message_new_tag(GstObject src, @Invalidate TagList tag_list);\n    @CallerOwnsReturn Message gst_message_new_buffering(GstObject src, int percent);\n    Pointer ptr_gst_message_new_buffering(GstObject src, int percent);\n    @CallerOwnsReturn Message gst_message_new_state_changed(GstObject src, State oldstate, State newstate, State pending);\n    Pointer ptr_gst_message_new_state_changed(GstObject src, State oldstate, State newstate, State pending);\n    @CallerOwnsReturn Message gst_message_new_state_dirty(GstObject src);\n    @CallerOwnsReturn Message gst_message_new_clock_provide(GstObject src, Clock clock, boolean ready);\n    @CallerOwnsReturn Message gst_message_new_clock_lost(GstObject src, Clock clock);\n    @CallerOwnsReturn Message gst_message_new_new_clock(GstObject src, Clock clock);\n    @CallerOwnsReturn Message gst_message_new_application(GstObject src, Structure structure);\n    @CallerOwnsReturn Message gst_message_new_element(GstObject src, Structure structure);\n    @CallerOwnsReturn Message gst_message_new_segment_start(GstObject src, Format format, long position);\n    @CallerOwnsReturn Message gst_message_new_segment_done(GstObject src, Format format, long position);\n    Pointer ptr_gst_message_new_segment_done(GstObject src, Format format, long position);\n    @CallerOwnsReturn Message gst_message_new_duration_changed(GstObject src);\n    Pointer ptr_gst_message_new_duration_changed(GstObject src);\n    @CallerOwnsReturn Message gst_message_new_async_start(GstObject src, boolean new_base_time);\n    @CallerOwnsReturn Message gst_message_new_async_done(GstObject src);\n    @CallerOwnsReturn Message gst_message_new_latency(GstObject src);\n    Pointer ptr_gst_message_new_latency(GstObject source);\n    @CallerOwnsReturn Message gst_message_new_custom(MessageType type, GstObject src, @Invalidate Structure structure);\n    @ConstReturn Structure gst_message_get_structure(Message message);\n    Pointer ptr_gst_message_new_need_context(GstObject source, String context_type);\n    @CallerOwnsReturn Message gst_message_new_need_context(GstObject source, String context_type);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstMessagePtr.java",
    "content": "/*\n * Copyright (c) 2020 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Pointer;\n\n/**\n * GstMessage pointer.\n */\npublic class GstMessagePtr extends GstMiniObjectPtr {\n\n    private static final int TYPE_OFFSET;\n    private static final int SRC_OFFSET;\n    \n    static {\n        GstMessageAPI.MessageStruct struct = new GstMessageAPI.MessageStruct();\n        TYPE_OFFSET = struct.typeOffset();\n        SRC_OFFSET = struct.srcOffset();\n    }\n    \n    \n    public GstMessagePtr() {\n    }\n\n    public GstMessagePtr(Pointer ptr) {\n        super(ptr);\n    }\n    \n    public int getMessageType() {\n        return getPointer().getInt(TYPE_OFFSET);\n    }\n\n    public GstObjectPtr getSource() {\n        Pointer raw = getPointer().getPointer(SRC_OFFSET);\n        return raw == null ? null : new GstObjectPtr(raw);\n    }\n    \n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstMetaAPI.java",
    "content": "package org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Library;\nimport com.sun.jna.Pointer;\nimport com.sun.jna.Structure;\n\n/**\n */\npublic interface GstMetaAPI extends Library {\n    GstMetaAPI GST_META_API = GstNative.load(GstMetaAPI.class);\n\n    \n\n    @Structure.FieldOrder({\"flags\", \"info\"})\n    class GstMetaStruct extends Structure {\n        public static final class ByValue extends GstMetaStruct implements Structure.ByValue {\n        }\n\n        public int flags;\n        public GstMetaInfoStruct.ByReference info;\n\n        int infoOffset() {\n            return fieldOffset(\"info\");\n        }\n        \n    }\n\n    @Structure.FieldOrder({\"api\", \"type\", \"size\"})\n    class GstMetaInfoStruct extends Structure {\n        public static class ByReference extends GstMetaInfoStruct implements Structure.ByReference {\n        }\n\n        public GstMetaInfoStruct() {\n        }\n\n        public GstMetaInfoStruct(Pointer p) {\n            super(p);\n            read();\n        }\n\n        public GType api;\n        public GType type;\n        public long size;\n        \n        int typeOffset() {\n            return fieldOffset(\"type\");\n        }\n        \n    }\n\n\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstMetaPtr.java",
    "content": "/*\n * Copyright (c) 2020 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Native;\nimport com.sun.jna.Pointer;\n\n/**\n * Base GstMeta pointer\n */\npublic class GstMetaPtr extends GTypedPtr {\n    \n    private static final int INFO_OFFSET;\n    private static final int IMPL_TYPE_OFFSET;\n    \n    static {\n        INFO_OFFSET = new GstMetaAPI.GstMetaStruct().infoOffset();\n        IMPL_TYPE_OFFSET = new GstMetaAPI.GstMetaInfoStruct().typeOffset();\n    }\n\n    public GstMetaPtr() {\n    }\n\n    public GstMetaPtr(Pointer ptr) {\n        super(ptr);\n    }\n\n    @Override\n    public GType getGType() {\n        // Quick getter for GType without allocation\n        Pointer metaInfo = getPointer().getPointer(INFO_OFFSET);\n        if (Native.SIZE_T_SIZE == 8) {\n            return GType.valueOf(metaInfo.getLong(IMPL_TYPE_OFFSET));\n        } else if (Native.SIZE_T_SIZE == 4) {\n            return GType.valueOf(((long) metaInfo.getInt(IMPL_TYPE_OFFSET)) & 0xffffffffL);\n        } else {\n            throw new IllegalStateException(\"SIZE_T size not supported: \" + Native.SIZE_T_SIZE);\n        }\n    }\n    \n    public GType getAPIGType() {\n        // Quick getter for GType without allocation\n        Pointer metaInfo = getPointer().getPointer(INFO_OFFSET);\n        if (Native.SIZE_T_SIZE == 8) {\n            return GType.valueOf(metaInfo.getLong(0));\n        } else if (Native.SIZE_T_SIZE == 4) {\n            return GType.valueOf(((long) metaInfo.getInt(0)) & 0xffffffffL);\n        } else {\n            throw new IllegalStateException(\"SIZE_T size not supported: \" + Native.SIZE_T_SIZE);\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstMiniObjectAPI.java",
    "content": "/*\n * Copyright (c) 2016 Christophe Lafolet\n * Copyright (c) 2014 Tom Greenwood <tgreenwood@cafex.com>\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Callback;\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.freedesktop.gstreamer.MiniObject;\nimport org.freedesktop.gstreamer.glib.GQuark;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI.GDestroyNotify;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\nimport org.freedesktop.gstreamer.lowlevel.annotations.Invalidate;\n\nimport com.sun.jna.Pointer;\n\n/**\n * GstMiniObject functions\n */\npublic interface GstMiniObjectAPI extends com.sun.jna.Library {\n    GstMiniObjectAPI GSTMINIOBJECT_API = GstNative.load(GstMiniObjectAPI.class);\n\n    void gst_mini_object_ref(GstMiniObjectPtr ptr);\n    void gst_mini_object_unref(GstMiniObjectPtr ptr);\n    void gst_mini_object_unref(Pointer ptr);\n    void gst_mini_object_weak_ref(GstMiniObjectPtr ptr, GstMiniObjectNotify notify,\n            IntPtr data);\n    void gst_mini_object_weak_unref(GstMiniObjectPtr ptr, GstMiniObjectNotify notify,\n            IntPtr data);\n\n    @CallerOwnsReturn MiniObject gst_mini_object_make_writable(@Invalidate MiniObject mini_object);\n    @CallerOwnsReturn MiniObject gst_mini_object_copy(MiniObject mini_object);\n    boolean gst_mini_object_is_writable(MiniObject mini_object);\n\n    void gst_mini_object_set_qdata(MiniObject mini_object, GQuark quark, Object data, GDestroyNotify destroyCallback);\n    Pointer gst_mini_object_get_qdata(MiniObject mini_object, GQuark quark);\n    Pointer gst_mini_object_steal_qdata(MiniObject mini_object, GQuark quark);\n\n    public static interface GstMiniObjectNotify extends Callback {\n\n        public void callback(IntPtr userData, Pointer obj);\n\n    }\n\n    public static final class MiniObjectStruct extends com.sun.jna.Structure {\n        public volatile GType type; \n        public volatile int refcount;\n        public volatile int lockstate;\n        public volatile int flags;\n        public volatile Pointer copyFn;\n        public volatile Pointer disposeFn;\n        public volatile Pointer freeFn;\n        public volatile int n_qdata; // Private parts - there for alignment\n        public volatile Pointer qdata;\n\n        /** Creates a new instance of GstMiniObjectStructure */\n        public MiniObjectStruct() {}\n        public MiniObjectStruct(Pointer ptr) {\n            super(ptr);\n        }\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"type\", \"refcount\", \"lockstate\", \"flags\",\n                \"copyFn\", \"disposeFn\", \"freeFn\", \"n_qdata\", \"qdata\"\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstMiniObjectPtr.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Native;\nimport com.sun.jna.Pointer;\n\n/**\n * Base MiniObject pointer\n */\npublic class GstMiniObjectPtr extends GTypedPtr {\n    \n    public GstMiniObjectPtr() {\n    }\n    \n    public GstMiniObjectPtr(Pointer ptr) {\n        super(ptr);\n    }\n    \n    @Override\n    public GType getGType() {\n        // Quick getter for GType without allocation\n        // same as : new MiniObjectStruct(ptr).type\n        if (Native.SIZE_T_SIZE == 8) {\n            return GType.valueOf(getPointer().getLong(0));\n        } else if (Native.SIZE_T_SIZE == 4) {\n            return GType.valueOf( ((long) getPointer().getInt(0)) & 0xffffffffL );\n        } else {\n            throw new IllegalStateException(\"SIZE_T size not supported: \" + Native.SIZE_T_SIZE);\n        }\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstNative.java",
    "content": "/* \n * Copyright (c) 2016 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport com.sun.jna.Library;\n\n/**\n * A convenience wrapper to aid in loading an API interface.\n */\n@SuppressWarnings(\"serial\")\npublic final class GstNative {\n    // gstreamer library names the files one of libfoo-0.10 and libfoo-1.0\n    // private static String[] nameFormats = { /*\"%s-0.10\",*/ \"%s-1.0\" };\n    private final static String[] nameFormats =\n            System.getProperty(\"gstreamer.GstNative.nameFormats\", \"%s-1.0\").split(\"\\\\|\");\n\n    private GstNative() {}\n    \n    private static final Map<String, Object> options = new HashMap<String, Object>() {{\n        put(Library.OPTION_TYPE_MAPPER, new GTypeMapper());\n        put(Library.OPTION_FUNCTION_MAPPER, new GFunctionMapper());\n    }};\n\n    public static <T extends Library> T load(Class<T> interfaceClass) {\n        return load(\"gstreamer\", interfaceClass);\n    }\n\n    public static <T extends Library> T load(String libraryName, Class<T> interfaceClass) {\n        for (String format : nameFormats)\n            try {\n                return GNative.loadLibrary(String.format(format, libraryName), interfaceClass, options);\n            } catch (UnsatisfiedLinkError ex) {\n                continue;\n            }\n        throw new UnsatisfiedLinkError(\"Could not load library: \" + libraryName);\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstNavigationAPI.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2009 Tamas Korodi <kotyo@zamba.fm>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.Structure;\nimport org.freedesktop.gstreamer.interfaces.Navigation;\n\nimport com.sun.jna.Library;\n\npublic interface GstNavigationAPI extends Library {\n\tGstNavigationAPI GSTNAVIGATION_API = GstNative.load(\"gstvideo\", GstNavigationAPI.class);\n\n\tGType gst_navigation_get_type();\n\n\t/* vitrual class functions */\n\tvoid gst_navigation_send_event(Navigation navigation, Structure structure);\n\n\tvoid gst_navigation_send_key_event(Navigation navigation, String event, String key);\n\n\tvoid gst_navigation_send_mouse_event(Navigation navigation, String event, \n\t\t\t\t\t\tint button, double x, double y);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstObjectAPI.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Callback;\nimport org.freedesktop.gstreamer.GstObject;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\nimport org.freedesktop.gstreamer.lowlevel.annotations.FreeReturnValue;\n\nimport com.sun.jna.NativeLong;\nimport com.sun.jna.Pointer;\nimport java.util.Arrays;\nimport java.util.List;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI.GList;\n\n/**\n * GstObject method and structures\n * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/gst/gstobject.h?h=1.8\n */\npublic interface GstObjectAPI extends com.sun.jna.Library {\n    \n    GstObjectAPI GSTOBJECT_API = GstNative.load(GstObjectAPI.class);\n\n    GType gst_object_get_type();\n    void gst_object_ref(GstObjectPtr ptr);\n    void gst_object_unref(GstObjectPtr ptr);\n    void gst_object_ref_sink(GstObjectPtr ptr);\n    \n    boolean gst_object_set_name(GstObject obj, String name);\n    @FreeReturnValue String gst_object_get_name(GstObject obj);\n    void gst_object_set_name_prefix(GstObject object, String name_prefix);\n    @FreeReturnValue String gst_object_get_name_prefix(GstObject object);\n    \n    /* parentage routines */\n    boolean gst_object_set_parent(GstObject object, GstObject parent);\n    @CallerOwnsReturn GstObject gst_object_get_parent(GstObject object);\n    void gst_object_unparent(GstObject object);\n    boolean gst_object_has_ancestor(GstObject object, GstObject ancestor);\n    \n    Pointer gst_implements_interface_cast(GstObject obj, NativeLong gtype);    \n    boolean gst_implements_interface_check(GstObject from, NativeLong type);\n    \n    /* controller functions */\n    long gst_object_suggest_next_sync(GstObjectPtr object);\n    boolean gst_object_sync_values(GstObjectPtr object, long timestamp);\n    boolean gst_object_has_active_control_bindings(GstObjectPtr object);\n    void gst_object_set_control_bindings_disabled(GstObjectPtr object, boolean disabled);\n    void gst_object_set_control_binding_disabled(GstObjectPtr object, String property_name, boolean disabled);\n    boolean gst_object_add_control_binding(GstObjectPtr object, GstControlBindingPtr binding);\n    GstControlBindingPtr gst_object_get_control_binding(GstObjectPtr object, String property_name);\n    boolean gst_object_remove_control_binding(GstObjectPtr object, GstControlBindingPtr binding);\n    \n    \n    /**\n    * GstObject:\n    * @lock: object LOCK\n    * @name: The name of the object\n    * @parent: this object's parent, weak ref\n    * @flags: flags for this object\n    *\n    * GStreamer base object class.\n    */\n    public static final class GstObjectStruct extends com.sun.jna.Structure {        \n        public GObjectAPI.GObjectStruct object;\n        \n        /*< public >*/ /* with LOCK */        \n        public volatile Pointer /* GMutex */ lock;  /* object LOCK */\n        public volatile String name;                /* object name */\n        public volatile Pointer /* GstObject */ parent; /* this object's parent, weak ref */\n        public volatile int flags;\n        \n        /*< private >*/\n        public volatile GList control_bindings;\n        public volatile long control_rate;\n        public volatile long last_sync;\n        \n        public volatile Pointer _gst_reserved;\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"object\",\n                \"lock\", \"name\", \"parent\", \"flags\",\n                \"control_bindings\", \"control_rate\", \"last_sync\",\n                \"_gst_reserved\"\n            });\n        }\n    }\n    \n    // -------------- Callbacks -----------------\n    public static interface DeepNotify extends Callback {\n        public void callback(GstObject object, GstObject orig, GObjectAPI.GParamSpec pspec);\n    }\n    \n    /**\n    * GstObjectClass:\n    * @parent_class: parent\n    * @path_string_separator: separator used by gst_object_get_path_string()\n    * @deep_notify: default signal handler\n    *\n    * GStreamer base object class.\n    */\n    public static final class GstObjectClass extends com.sun.jna.Structure {\n        public GObjectAPI.GObjectClass parent_class;\n        \n        public volatile String path_string_separator;\n        \n        /* signals */\n        public DeepNotify deep_notify;\n        \n        public volatile Pointer[] _gst_reserved = new Pointer[GstAPI.GST_PADDING];\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"parent_class\", \"path_string_separator\",\n                \"deep_notify\", \n                \"_gst_reserved\"\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstObjectPtr.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Pointer;\n\n/**\n * Base GObject pointer\n */\npublic class GstObjectPtr extends GObjectPtr {\n    \n    public GstObjectPtr() {\n    }\n    \n    public GstObjectPtr(Pointer ptr) {\n        super(ptr);\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstPadAPI.java",
    "content": "/* \n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2018 Antonio Morales\n * Copyright (c) 2014 Tom Greenwood <tgreenwood@cafex.com>\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.Buffer;\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.Element;\nimport org.freedesktop.gstreamer.event.Event;\nimport org.freedesktop.gstreamer.FlowReturn;\nimport org.freedesktop.gstreamer.Pad;\nimport org.freedesktop.gstreamer.PadDirection;\nimport org.freedesktop.gstreamer.PadLinkReturn;\nimport org.freedesktop.gstreamer.PadProbeReturn;\nimport org.freedesktop.gstreamer.PadTemplate;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI.GDestroyNotify;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\nimport org.freedesktop.gstreamer.lowlevel.annotations.FreeReturnValue;\nimport org.freedesktop.gstreamer.lowlevel.annotations.IncRef;\n\nimport com.sun.jna.NativeLong;\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.query.Query;\n\n/**\n * GstPad functions\n */\npublic interface GstPadAPI extends com.sun.jna.Library {\n\tpublic static final int GST_PAD_PROBE_TYPE_INVALID\t\t \t= 0;\n\t/* flags to control blocking */\n\tpublic static final int GST_PAD_PROBE_TYPE_IDLE \t\t\t= (1 << 0);\n\tpublic static final int GST_PAD_PROBE_TYPE_BLOCK \t\t\t= (1 << 1);\n\t/* flags to select datatypes */\n\tpublic static final int GST_PAD_PROBE_TYPE_BUFFER \t\t\t= (1 << 4);\n\tpublic static final int GST_PAD_PROBE_TYPE_BUFFER_LIST      = (1 << 5);\n\tpublic static final int GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM = (1 << 6);\n\tpublic static final int GST_PAD_PROBE_TYPE_EVENT_UPSTREAM   = (1 << 7);\n\tpublic static final int GST_PAD_PROBE_TYPE_EVENT_FLUSH      = (1 << 8);\n\tpublic static final int GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM = (1 << 9);\n\tpublic static final int GST_PAD_PROBE_TYPE_QUERY_UPSTREAM   = (1 << 10);\n\t/* flags to select scheduling mode */\n\tpublic static final int GST_PAD_PROBE_TYPE_PUSH             = (1 << 12);\n\tpublic static final int GST_PAD_PROBE_TYPE_PULL             = (1 << 13);\n\tpublic static final int GST_PAD_PROBE_TYPE_BLOCKING         = GST_PAD_PROBE_TYPE_IDLE | GST_PAD_PROBE_TYPE_BLOCK;\n\tpublic 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;\n\tpublic static final int GST_PAD_PROBE_TYPE_DATA_UPSTREAM    = GST_PAD_PROBE_TYPE_EVENT_UPSTREAM;\n\tpublic static final int GST_PAD_PROBE_TYPE_DATA_BOTH        = GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM | GST_PAD_PROBE_TYPE_DATA_UPSTREAM;\n\tpublic static final int GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM = GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM;\n\tpublic static final int GST_PAD_PROBE_TYPE_BLOCK_UPSTREAM   = GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_DATA_UPSTREAM;\n\tpublic static final int GST_PAD_PROBE_TYPE_EVENT_BOTH       = GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GST_PAD_PROBE_TYPE_EVENT_UPSTREAM;\t\t  \n\tpublic static final int GST_PAD_PROBE_TYPE_QUERY_BOTH       = GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM | GST_PAD_PROBE_TYPE_QUERY_UPSTREAM;\n\tpublic static final int GST_PAD_PROBE_TYPE_ALL_BOTH         = GST_PAD_PROBE_TYPE_DATA_BOTH | GST_PAD_PROBE_TYPE_QUERY_BOTH;\n\tpublic static final int GST_PAD_PROBE_TYPE_SCHEDULING       = GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_PULL;\n\t\n    static GstPadAPI GSTPAD_API = GstNative.load(GstPadAPI.class);\n    \n    GType gst_pad_get_type();\n    GType gst_ghost_pad_get_type();\n    @CallerOwnsReturn Pad gst_pad_new(String name, PadDirection direction);\n    @CallerOwnsReturn Pad gst_pad_new_from_template(PadTemplate templ, String name);\n    @CallerOwnsReturn Pointer ptr_gst_pad_new(String name, PadDirection direction);\n    @CallerOwnsReturn Pointer ptr_gst_pad_new_from_template(PadTemplate templ, String name);\n    @FreeReturnValue String gst_pad_get_name(Pad pad);\n    PadLinkReturn gst_pad_link(Pad src, Pad sink);\n    boolean gst_pad_unlink(Pad src, Pad sink);\n    boolean gst_pad_is_linked(Pad pad);\n    @CallerOwnsReturn Pad gst_pad_get_peer(Pad pad);\n    PadDirection gst_pad_get_direction(Pad pad);\n    /* pad functions from gstutils.h */\n    boolean gst_pad_can_link(Pad srcpad, Pad sinkpad);\n\n    void gst_pad_use_fixed_caps(Pad pad);\n    @CallerOwnsReturn Caps gst_pad_get_fixed_caps_func(Pad pad);\n    @CallerOwnsReturn Caps gst_pad_proxy_getcaps(Pad pad);\n    boolean gst_pad_proxy_setcaps(Pad pad, Caps caps);\n    @CallerOwnsReturn Element gst_pad_get_parent_element(Pad pad);\n    \n\n    boolean gst_pad_set_active(Pad pad, boolean active);\n    boolean gst_pad_is_active(Pad pad);\n    boolean gst_pad_activate_pull(Pad pad, boolean active);\n    boolean gst_pad_activate_push(Pad pad, boolean active);\n    boolean gst_pad_is_blocked(Pad pad);\n    boolean gst_pad_is_blocking(Pad pad);\n    boolean gst_pad_has_current_caps(Pad pad);\n    /* get_pad_template returns a non-refcounted PadTemplate */\n    PadTemplate gst_pad_get_pad_template(Pad pad);\n    \n    /* capsnego function for connected/unconnected pads */\n    @CallerOwnsReturn Caps gst_pad_query_caps(Pad pad, Caps caps);\n    void gst_pad_fixate_caps(Pad pad, Caps caps);\n    boolean gst_pad_query_accept_caps(Pad pad, Caps caps);\n//    boolean gst_pad_set_caps(Pad pad, Caps caps);\n    @CallerOwnsReturn Caps gst_pad_peer_query_caps(Pad pad, Caps caps);\n    boolean gst_pad_peer_query_accept_caps(Pad pad, Caps caps);\n    \n    /* capsnego for connected pads */\n    @CallerOwnsReturn Caps gst_pad_get_allowed_caps(Pad pad);\n    @CallerOwnsReturn Caps gst_pad_get_current_caps(Pad pad);\n\n    /* data passing functions to peer */\n    FlowReturn gst_pad_push(Pad pad, @IncRef Buffer buffer);\n    boolean gst_pad_check_pull_range(Pad pad);\n    FlowReturn gst_pad_pull_range(Pad pad, /* guint64 */ long offset, /* guint */ int size,\n            Buffer[] buffer);\n    boolean gst_pad_push_event(Pad pad, @IncRef Event event);\n    boolean gst_pad_event_default(Pad pad, Event event);\n    /* data passing functions on pad */\n    FlowReturn gst_pad_chain(Pad pad, @IncRef Buffer buffer);\n    FlowReturn gst_pad_get_range(Pad pad, /* guint64 */ long offset, /* guint */ int size,\n        Buffer[] buffer);\n    boolean gst_pad_send_event(Pad pad, @IncRef Event event);\n    public static interface PadFixateCaps extends GstCallback {\n        void callback(Pad pad, Caps caps);\n    }\n    void gst_pad_set_fixatecaps_function(Pad pad, PadFixateCaps fixate);\n    \n    /* probes */\n//    public static interface PadDataProbe extends GstCallback {\n//        void callback(Pad pad, Buffer buffer, Pointer user_data);\n//    }\n//    public static interface PadEventProbe extends GstCallback {\n//        boolean callback(Pad pad, Event ev, Pointer user_data);\n//    }\n    \n    public static interface PadProbeCallback extends GstCallback {\n        public PadProbeReturn callback(Pad pad, GstPadProbeInfo probeInfo, Pointer user_data);\n    }\n    \n    /**\n     * \n     * @param pad\n     * @param mask The type comes from the constants in GstPadProbeType\n     * @param callback\n     * @param user_data\n     * @param destroy_data\n     * @return\n     */\n    NativeLong gst_pad_add_probe(GstPadPtr pad, int mask, PadProbeCallback callback, \n    \t\tPointer user_data, GDestroyNotify destroy_data);\n    void gst_pad_remove_probe(GstPadPtr pad, NativeLong id);\n    \n    Event gst_pad_probe_info_get_event(GstPadProbeInfo probeInfo);\n\n    Buffer gst_pad_probe_info_get_buffer(GstPadProbeInfo probeInfo);\n    \n    Query gst_pad_probe_info_get_query(GstPadProbeInfo probeInfo);\n\n//    NativeLong /* gulong */ gst_pad_add_data_probe(Pad pad, PadDataProbe handler, Pointer data);\n//\n//    void gst_pad_remove_data_probe(Pad pad, NativeLong handler_id);\n//\n//    NativeLong /* gulong */ gst_pad_add_event_probe(Pad pad, PadEventProbe handler, Pointer data);\n//\n//    void gst_pad_remove_event_probe(Pad pad, NativeLong handler_id);\n//\n//    NativeLong /* gulong */ gst_pad_add_buffer_probe(Pad pad, GstCallback handler, Pointer data);\n//\n//    void gst_pad_remove_buffer_probe(Pad pad, NativeLong handler_id);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstPadProbeInfo.java",
    "content": "/*\n * Copyright (c) 2014 Tom Greenwood <tgreenwood@cafex.com>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport java.util.Arrays;\nimport java.util.List;\n\nimport com.sun.jna.NativeLong;\nimport com.sun.jna.Pointer;\nimport com.sun.jna.Structure;\nimport static org.freedesktop.gstreamer.lowlevel.GstAPI.GST_PADDING;\n\n/**\n * GstPadProbeInfo structure\n * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/gst/gstpad.h?h=1.8\n */\npublic class GstPadProbeInfo extends Structure {\n    \n    public volatile int padProbeType;   // GstPadProbeInfo enum constants\n    public volatile NativeLong id;      // id of the probe\n    public volatile Pointer data;       // (allow-none): type specific data, check the @type field to know the datatype. This field can be %NULL.\n    public volatile long offset;        // offset of pull probe, this field is valid when type contains GST_PAD_PROBE_TYPE_PULL\n    public volatile int size;           // size of pull probe, this field is valid when type contains GST_PAD_PROBE_TYPE_PULL\n\n    /*< private >*/\n    public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING];\n    \n    @Override\n    protected List<String> getFieldOrder() {\n        return Arrays.asList(new String[] {\n            \"padProbeType\", \"id\", \"data\", \"offset\", \"size\",\n            \"_gst_reserved\"\n        });\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstPadPtr.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Pointer;\n\n/**\n * Base GObject pointer\n */\npublic class GstPadPtr extends GstObjectPtr {\n    \n    public GstPadPtr() {\n    }\n    \n    public GstPadPtr(Pointer ptr) {\n        super(ptr);\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstPadTemplateAPI.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Native;\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.Pad;\nimport org.freedesktop.gstreamer.PadDirection;\nimport org.freedesktop.gstreamer.PadPresence;\nimport org.freedesktop.gstreamer.PadTemplate;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\nimport org.freedesktop.gstreamer.lowlevel.annotations.IncRef;\n\nimport com.sun.jna.Pointer;\nimport com.sun.jna.PointerType;\n\n/**\n * GstPadTemplate functions\n */\npublic interface GstPadTemplateAPI extends com.sun.jna.Library {\n    GstPadTemplateAPI GSTPADTEMPLATE_API = GstNative.load(GstPadTemplateAPI.class);\n\n    /* element class pad templates */\n    void gst_element_class_add_pad_template(Pointer klass, PadTemplate templ);\n    PadTemplate gst_element_class_get_pad_template(Pointer /*GstElementClass*/ element_class, String name);\n    \n    /* templates and factories */\n    GType gst_pad_template_get_type();\n    GType gst_static_pad_template_get_type();\n\n    @CallerOwnsReturn Pointer ptr_gst_pad_template_new(String name_template, PadDirection direction, \n            PadPresence presence, @IncRef Caps caps);\n    @CallerOwnsReturn PadTemplate gst_pad_template_new(String name_template, PadDirection direction, \n            PadPresence presence, @IncRef Caps caps);\n    @CallerOwnsReturn PadTemplate gst_static_pad_template_get(GstStaticPadTemplate pad_template);\n    @CallerOwnsReturn Caps gst_static_pad_template_get_caps(GstStaticPadTemplate template);\n    @CallerOwnsReturn Caps gst_pad_template_get_caps(PadTemplate template);\n    void gst_pad_template_pad_created(PadTemplate templ, Pad pad);\n    \n    public static final class GstStaticPadTemplate extends PointerType {\n\n        public GstStaticPadTemplate() {\n        }\n\n        public GstStaticPadTemplate(Pointer p) {\n            super(p);\n        }\n        \n        public String getName() {\n            return getPointer().getPointer(0).getString(0);\n        }\n        \n        public PadDirection getPadDirection() {\n            return PadDirection.values()[getPointer().getInt(Native.POINTER_SIZE)];\n        }\n        \n        public PadPresence getPadPresence() {\n            return PadPresence.values()[getPointer().getInt(Native.POINTER_SIZE + 4)];\n        }\n    }  \n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstParseAPI.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.Bin;\nimport org.freedesktop.gstreamer.Pipeline;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\n\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.Element;\n\n/**\n * gstparse functions\n */\npublic interface GstParseAPI extends com.sun.jna.Library {\n\tGstParseAPI GSTPARSE_API = GstNative.load(GstParseAPI.class);\n\n    @CallerOwnsReturn Element gst_parse_launch(String pipeline_description, Pointer[] error);\n    @CallerOwnsReturn Element gst_parse_launchv(String[] pipeline_description, Pointer[] error);\n    @CallerOwnsReturn Element gst_parse_launch(String pipeline_description, GstAPI.GErrorStruct[] error);\n    @CallerOwnsReturn Element gst_parse_launchv(String[] pipeline_description, GstAPI.GErrorStruct[] error);\n    @CallerOwnsReturn Bin gst_parse_bin_from_description(String bin_description, boolean ghost_unlinked_pads,Pointer[] error);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstPipelineAPI.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.Bus;\nimport org.freedesktop.gstreamer.Clock;\nimport org.freedesktop.gstreamer.Pipeline;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\n\nimport com.sun.jna.Pointer;\n\n/**\n * GstPipeline\n */\npublic interface GstPipelineAPI extends com.sun.jna.Library {\n\tGstPipelineAPI GSTPIPELINE_API = GstNative.load(GstPipelineAPI.class);\n\n    @CallerOwnsReturn Pipeline gst_pipeline_new(String name);\n    @CallerOwnsReturn Pointer ptr_gst_pipeline_new(String name);\n    GType gst_pipeline_get_type();\n    @CallerOwnsReturn Bus gst_pipeline_get_bus(Pipeline pipeline);\n    void gst_pipeline_set_auto_flush_bus(Pipeline pipeline, boolean flush);\n    boolean gst_pipeline_get_auto_flush_bus(Pipeline pipeline);\n    void gst_pipeline_set_new_stream_time(Pipeline pipeline, long time);\n    long gst_pipeline_get_last_stream_time(Pipeline pipeline);\n    void gst_pipeline_use_clock(Pipeline pipeline, Clock clock);\n    boolean gst_pipeline_set_clock(Pipeline pipeline, Clock clock);\n    @CallerOwnsReturn Clock gst_pipeline_get_clock(Pipeline pipeline);\n    void gst_pipeline_auto_clock(Pipeline pipeline);\n    void gst_pipeline_set_delay(Pipeline pipeline, long delay);\n    long gst_pipeline_get_delay(Pipeline pipeline);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstPluginAPI.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.Plugin;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI.GList;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\n\n/**\n * GstPlugin functions\n */\npublic interface GstPluginAPI extends com.sun.jna.Library {\n\tGstPluginAPI GSTPLUGIN_API = GstNative.load(GstPluginAPI.class);\n\n    GType gst_plugin_get_type();\n\n    String gst_plugin_get_name(Plugin plugin);\n    String gst_plugin_get_description(Plugin plugin);\n    String gst_plugin_get_filename(Plugin plugin);\n    String gst_plugin_get_version(Plugin plugin);\n    String gst_plugin_get_license(Plugin plugin);\n    String gst_plugin_get_source(Plugin plugin);\n    String gst_plugin_get_package(Plugin plugin);\n    String gst_plugin_get_origin(Plugin plugin);\n    String gst_plugin_get_release_date_string(Plugin plugin);\n    boolean gst_plugin_is_loaded(Plugin plugin);\n    boolean gst_plugin_name_filter(Plugin plugin, String name);\n\n    //Plugin \t\tgst_plugin_load_file\t\t(String filename, GError** error);\n\n    @CallerOwnsReturn Plugin gst_plugin_load(Plugin plugin);\n    @CallerOwnsReturn Plugin gst_plugin_load_by_name(String name);\n\n    void gst_plugin_list_free(GList list);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstPluginFeatureAPI.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.Plugin;\nimport org.freedesktop.gstreamer.PluginFeature;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI.GList;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\n\n/**\n * GstPluginFeature functions\n */\npublic interface GstPluginFeatureAPI extends com.sun.jna.Library {\n    GstPluginFeatureAPI GSTPLUGINFEATURE_API = GstNative.load(GstPluginFeatureAPI.class);\n\n    /* normal GObject stuff */\n    GType gst_plugin_feature_get_type();\n\n    @CallerOwnsReturn PluginFeature gst_plugin_feature_load(PluginFeature feature);\n\n    void gst_plugin_feature_set_rank(PluginFeature feature, int rank);\n    int gst_plugin_feature_get_rank(PluginFeature feature);\n    String gst_plugin_feature_get_plugin_name(PluginFeature feature);\n    @CallerOwnsReturn Plugin gst_plugin_feature_get_plugin(PluginFeature feature);\n\n    boolean gst_plugin_feature_check_version(PluginFeature feature,\n            int min_major, int min_minor, int min_micro);\n\n    void gst_plugin_feature_list_free (GList list);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstPromiseAPI.java",
    "content": "/*\n * Copyright (c) 2018 Vinicius Tona\n * Copyright (c) 2018 Antonio Morales\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.freedesktop.gstreamer.Promise;\nimport org.freedesktop.gstreamer.PromiseResult;\nimport org.freedesktop.gstreamer.Structure;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback;\nimport org.freedesktop.gstreamer.lowlevel.GstMiniObjectAPI.MiniObjectStruct;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\n\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.lowlevel.annotations.Invalidate;\n\n/**\n * GstPromise methods and structures\n * \n * @see https://github.com/GStreamer/gstreamer/blob/master/gst/gstpromise.h\n * available since GStreamer 1.14\n */\npublic interface GstPromiseAPI extends com.sun.jna.Library {\n  GstPromiseAPI GSTPROMISE_API = GstNative.load(GstPromiseAPI.class);\n\n  public static final class PromiseStruct extends com.sun.jna.Structure {\n    public volatile MiniObjectStruct parent;\n\n    public PromiseStruct() {\n    }\n\n    public PromiseStruct(Pointer ptr) {\n      useMemory(ptr);\n    }\n\n    @Override\n    protected List<String> getFieldOrder() {\n      return Arrays.asList(new String[] { \"parent\" });\n    }\n  }\n\n  GType gst_promise_get_type();\n  GType gst_static_promise_get_type();\n\n  @CallerOwnsReturn Promise gst_promise_new();\n  @CallerOwnsReturn Pointer ptr_gst_promise_new();\n\n  @CallerOwnsReturn Promise gst_promise_new_with_change_func(GstCallback callback, Pointer userData, Pointer destroyNotify);\n  @CallerOwnsReturn Pointer ptr_gst_promise_new_with_change_func(GstCallback callback, Pointer userData, Pointer destroyNotify);\n\n  PromiseResult gst_promise_wait(Promise promise);\n\n  void gst_promise_reply(Promise promise, @Invalidate Structure s);\n  void gst_promise_interrupt(Promise promise);\n  void gst_promise_expire(Promise promise);\n\n  @CallerOwnsReturn Structure gst_promise_get_reply(Promise promise);\n  @CallerOwnsReturn Pointer ptr_gst_promise_get_reply(Promise promise);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstProxyControlBindingPtr.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Pointer;\n\n/**\n * \n */\npublic class GstProxyControlBindingPtr extends GstControlBindingPtr {\n    \n    public GstProxyControlBindingPtr() {\n    }\n    \n    public GstProxyControlBindingPtr(Pointer ptr) {\n        super(ptr);\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstQueryAPI.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.freedesktop.gstreamer.BufferPool;\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.Format;\nimport org.freedesktop.gstreamer.query.Query;\nimport org.freedesktop.gstreamer.query.QueryType;\nimport org.freedesktop.gstreamer.Structure;\nimport org.freedesktop.gstreamer.glib.GQuark;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\n\nimport com.sun.jna.Pointer;\n\n/**\n * GstQueryAPI functions and structure\n * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/gst/gstquery.h?h=1.8\n */\npublic interface GstQueryAPI extends com.sun.jna.Library {\n    GstQueryAPI GSTQUERY_API = GstNative.load(GstQueryAPI.class);\n\n    String gst_query_type_get_name(QueryType query);\n    GQuark gst_query_type_to_quark(QueryType query);\n\n    /* position query */\n    @CallerOwnsReturn Query gst_query_new_position(Format format);\n    @CallerOwnsReturn Pointer ptr_gst_query_new_position(Format format);\n    void gst_query_set_position(Query query, Format format, /* gint64 */ long cur);\n    void gst_query_parse_position(Query query, Format[] format, /* gint64 * */ long[] cur);\n\n    /* duration query */\n    @CallerOwnsReturn Query gst_query_new_duration(Format format);\n    @CallerOwnsReturn Pointer ptr_gst_query_new_duration(Format format);\n    void gst_query_set_duration(Query query, Format format, /* gint64 */ long duration);\n    void gst_query_parse_duration(Query query, /* Format **/ Format[] format, /* gint64 * */ long[] duration);\n\n    /* latency query */\n    @CallerOwnsReturn Query gst_query_new_latency();\n    @CallerOwnsReturn Pointer ptr_gst_query_new_latency();\n    void gst_query_set_latency(Query query, boolean live, long min_latency,\n         long max_latency);\n    void gst_query_parse_latency(Query query, boolean[] live, long[] min_latency, \n\t\t                                 long[] max_latency);\n\n    /* convert query */\n    @CallerOwnsReturn Query gst_query_new_convert(Format src_format, /* gint64 */ long value, Format dest_format);\n    @CallerOwnsReturn Pointer ptr_gst_query_new_convert(Format src_format, /* gint64 */ long value, Format dest_format);\n    void gst_query_set_convert(Query query, Format src_format, /* gint64 */ long src_value,\n\t\t\t\t\t\t Format dest_format, /* gint64 */ long dest_value);\n    void gst_query_parse_convert(Query query, Format[] src_format, /*gint64 **/ long[] src_value,\n\t\t\t\t\t\t Format[] dest_format, /*gint64 **/ long[] dest_value);\n    /* segment query */\n    @CallerOwnsReturn Query gst_query_new_segment(Format format);\n    @CallerOwnsReturn Pointer ptr_gst_query_new_segment(Format format);\n    void gst_query_set_segment(Query query, double rate, Format format,\n         /* gint64 */ long start_value, /* gint64 */ long stop_value);\n    void gst_query_parse_segment(Query query, double[] rate, Format[] format,\n         /* gint64 * */ long[] start_value, /* gint64 * */ long[] stop_value);\n\n    Structure gst_query_get_structure(Query query);\n\n    /* seeking query */\n    @CallerOwnsReturn Query gst_query_new_seeking(Format format);\n    @CallerOwnsReturn Pointer ptr_gst_query_new_seeking(Format format);\n    void gst_query_set_seeking(Query query, Format format,\n        boolean seekable, /* gint64 */ long segment_start, /* gint64 */ long segment_end);\n    void gst_query_parse_seeking(Query query, Format[] format,\n        boolean[] seekable, /* gint64 * */ long[] segment_start, /* gint64 * */ long[] segment_end);\n    /* formats query */\n    @CallerOwnsReturn Query gst_query_new_formats();\n    Pointer ptr_gst_query_new_formats();\n    void gst_query_set_formats(Query query, int n_formats, Format... formats);\n    void gst_query_set_formatsv(Query query, int n_formats, Format[] formats);\n    void gst_query_parse_n_formats(Query query, int[] n_formats);\n    void gst_query_parse_nth_format(Query query, int nth, Format[] format);\n    \n    /* allocation query */\n    @CallerOwnsReturn Query gst_query_new_allocation(Caps caps, boolean need_pool);\n    Pointer ptr_gst_query_new_allocation(Caps caps, boolean need_pool);\n    void gst_query_parse_allocation(Query query, /* Caps ** */ Pointer[] caps, boolean[] need_pool);\n    void gst_query_add_allocation_meta(Query query, GType api, Structure params);\n    void gst_query_add_allocation_pool(Query query, BufferPool pool, /* guint */ int size, /* guint */ int min_buffers, /* guint */ int max_buffers);\n    int gst_query_get_n_allocation_pools(Query query);\n\n    \n    public static final class QueryStruct extends com.sun.jna.Structure {\n        public volatile GstMiniObjectAPI.MiniObjectStruct mini_object;\n        \n        /*< public > *//* with COW */\n        public volatile QueryType type;\n        \n        public QueryStruct(Pointer ptr) {\n            useMemory(ptr);\n        }\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"mini_object\", \"type\"\n            });\n        }\n    }\n    \n    public interface GstQueryTypeFlags {\n        public static final int UPSTREAM = 1;\n        public static final int DOWNSTREAM = 1 << 1;\n        public static final int SERIALIZED = 1 << 2;\n        public static final int BOTH = UPSTREAM | DOWNSTREAM;\n    }\n    \n    public static final int GST_QUERY_NUM_SHIFT = 8;\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstRegistryAPI.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.Plugin;\nimport org.freedesktop.gstreamer.PluginFeature;\nimport org.freedesktop.gstreamer.Registry;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\n\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI.GList;\n\n/**\n * GstRegistry functions\n */\npublic interface GstRegistryAPI extends com.sun.jna.Library {\n\tGstRegistryAPI GSTREGISTRY_API = GstNative.load(GstRegistryAPI.class);\n\n    /* function for filters */\n    static interface PluginFilter extends GstCallback {\n        /**\n         *\n         * A function that can be used with e.g. gst_registry_plugin_filter()\n         * to get a list of plugins that match certain criteria.\n         *\n         * @param plugin the plugin to check\n         * @param user_data the user_data that has been passed on e.g. {@link GstRegistryAPI#gst_registry_feature_filter}\n         * @return true for a positive match, false otherwise\n         */\n        boolean callback(Plugin plugin, Pointer user_data);\n    }\n\n    \n    static interface PluginFeatureFilter extends GstCallback {\n        /**\n         * A function that can be used with e.g. gst_registry_feature_filter()\n         * to get a list of pluginfeature that match certain criteria.\n         * @param feature the pluginfeature to check\n         * @param user_data the user_data that has been passed on e.g. {@link GstRegistryAPI#gst_registry_feature_filter}\n         * @return true if this plugin feature is accepted.\n         */\n        boolean callback(PluginFeature feature, Pointer user_data);\n    }\n\n    /* normal GObject stuff */\n    GType gst_registry_get_type();\n    /* registry_get_default returns a non-refcounted object */\n    Pointer gst_registry_get();\n    \n    GList gst_registry_get_feature_list(Registry registry, GType type);\n    int gst_registry_get_feature_list_cookie (Registry registry);\n    GList gst_registry_get_feature_list_by_plugin(Registry registry, String name);\n    GList gst_registry_get_plugin_list(Registry registry);\n    boolean gst_registry_add_plugin(Registry registry, Plugin plugin);\n    void gst_registry_remove_plugin(Registry registry, Plugin plugin);\n    GList gst_registry_plugin_filter(Registry registry, PluginFilter filter, boolean first, Pointer user_data);\n    GList gst_registry_feature_filter(Registry registry, PluginFeatureFilter filter, boolean first, Pointer user_data);\n    @CallerOwnsReturn Plugin gst_registry_find_plugin(Registry registry, String name);\n    @CallerOwnsReturn PluginFeature gst_registry_find_feature(Registry registry, String name, GType type);\n    @CallerOwnsReturn PluginFeature gst_registry_lookup_feature(Registry registry, String name);\n    void gst_registry_add_path(Registry registry, String path);\n    GList gst_registry_get_path_list(Registry registry);\n    boolean gst_registry_scan_path(Registry registry, String path);\n    @CallerOwnsReturn Plugin gst_registry_lookup(Registry registry, String filename);\n    void gst_registry_remove_feature(Registry  registry, PluginFeature feature);\n    boolean gst_registry_add_feature(Registry  registry, PluginFeature feature);\n    boolean gst_registry_check_feature_version (Registry registry, String feature_name, int min_major, int min_minor, int min_micro);\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstSDPMessageAPI.java",
    "content": "/*\n * Copyright (c) 2018 Antonio Morales\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel; \n\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.freedesktop.gstreamer.SDPResult;\nimport org.freedesktop.gstreamer.SDPMessage;\nimport org.freedesktop.gstreamer.lowlevel.GValueAPI.GValueArray;\n\nimport com.sun.jna.Pointer;\n\n/**\n * GstSDPMessage methods and structures\n *\n * @see https://github.com/GStreamer/gst-plugins-base/blob/master/gst-libs/gst/sdp/gstsdpmessage.h\n */\npublic interface GstSDPMessageAPI extends com.sun.jna.Library {\n  GstSDPMessageAPI GSTSDPMESSAGE_API = GstNative.load(\"gstsdp\", GstSDPMessageAPI.class);\n\n  public static final class SDPMessageStruct extends com.sun.jna.Structure {\n    public volatile String version;\n    public volatile SDPOriginStruct origin;\n    public volatile String session_name;\n    public volatile String information;\n    public volatile String uri;\n    public volatile GValueArray emails;\n    public volatile GValueArray phones;\n    public volatile SDPConnectionStruct connection;\n    public volatile GValueArray bandwidths;\n    public volatile GValueArray times;\n    public volatile GValueArray zones;\n    public volatile SDPKeyStruct key;\n    public volatile GValueArray attributes;\n    public volatile GValueArray medias;\n\n    public SDPMessageStruct(final Pointer ptr) {\n        useMemory(ptr);\n    }\n\n    @Override\n    protected List<String> getFieldOrder() {\n        return Arrays.asList(new String[] {\n          \"version\", \"origin\", \"session_name\", \"information\", \"uri\",\n          \"emails\", \"phones\", \"connection\", \"bandwidths\", \"times\",\n          \"zones\", \"key\", \"attributes\", \"medias\"\n        });\n    }\n  }\n\n  public static final class SDPOriginStruct extends com.sun.jna.Structure {\n    public volatile String username;\n    public volatile String sess_id;\n    public volatile String sess_version;\n    public volatile String nettype;\n    public volatile String addrtype;\n    public volatile String addr;\n\n    public SDPOriginStruct(final Pointer ptr) {\n        useMemory(ptr);\n    }\n\n    @Override\n    protected List<String> getFieldOrder() {\n        return Arrays.asList(new String[] {\n          \"username\", \"sess_id\", \"sess_version\", \"nettype\", \"addrtype\", \"addr\" \n        });\n    }\n  }\n\n  public static final class SDPKeyStruct extends com.sun.jna.Structure {\n    public volatile String type;\n    public volatile String data;\n\n    public SDPKeyStruct(final Pointer ptr) {\n        useMemory(ptr);\n    }\n\n    @Override\n    protected List<String> getFieldOrder() {\n        return Arrays.asList(new String[] { \"type\", \"data\" });\n    }\n  }\n\n  public static final class SDPConnectionStruct extends com.sun.jna.Structure {\n    public volatile String nettype;\n    public volatile String addrtype;\n    public volatile String address;\n    public volatile int ttl;\n    public volatile int addr_number;\n\n    public SDPConnectionStruct(final Pointer ptr) {\n        useMemory(ptr);\n    }\n\n    @Override \n    protected List<String> getFieldOrder() {\n        return Arrays.asList(new String[] {\n          \"nettype\", \"addrtype\", \"address\", \"ttl\", \"addr_number\" \n        });\n    }\n  }\n\n  SDPResult gst_sdp_connection_set(SDPConnectionStruct conn, String nettype, String address, int ttl, int addr_number);\n  SDPResult gst_sdp_connection_clear(SDPConnectionStruct conn);\n\n  SDPResult gst_sdp_message_free(Pointer msg);\n  SDPResult ptr_gst_sdp_message_free(Pointer msg);\n\n  SDPResult gst_sdp_message_new(Pointer[] msg);\n\n  SDPResult gst_sdp_message_parse_buffer(byte[] data, int size, Pointer[] msg);\n  SDPResult gst_sdp_message_parse_buffer(byte[] data, int size, SDPMessage msg);\n  SDPResult gst_sdp_message_copy(SDPMessage msg, Pointer[] copy);\n\n  String gst_sdp_message_as_text(SDPMessage msg);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstSampleAPI.java",
    "content": "/* \n * Copyright (c) 2020 Christophe Lafolet\n * Copyright (c) 2015 Neil C Smith\n * Copyright (c) 2014 Tom Greenwood <tgreenwood@cafex.com>\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.freedesktop.gstreamer.Buffer;\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.Sample;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GstSegmentStruct;\nimport org.freedesktop.gstreamer.lowlevel.GstMiniObjectAPI.MiniObjectStruct;\n\nimport com.sun.jna.Pointer;\n\n/**\n * GstSampleAPI functions and structure\n * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/gst/gstsample.c?h=1.8\n */\npublic interface GstSampleAPI extends com.sun.jna.Library {\n    GstSampleAPI GSTSAMPLE_API = GstNative.load(GstSampleAPI.class);\n\n    public static final class SampleStruct extends com.sun.jna.Structure {\n    \tpublic volatile MiniObjectStruct mini_object;\n        \n        public volatile Pointer /* GstBuffer* */buffer;             // to Buffer\n        public volatile Pointer /* GstCaps* */ caps;                // to Caps\n        public volatile GstSegmentStruct segment;                   // Segment\n        public volatile Pointer /* GstStructure* */ info;           // to Strucutre\n        public volatile Pointer /* GstBufferList* */ buffer_list;   // to buffer_list\n        \n        /**\n         * Creates a new instance of MessageStruct\n         */\n        public SampleStruct() {\n        }\n        public SampleStruct(Pointer ptr) {\n            useMemory(ptr);\n        }\n\n        @Override\n        protected List<String> getFieldOrder() {\n            return Arrays.asList(new String[]{\n                \"mini_object\", \"buffer\", \"caps\", \"segment\", \"info\", \"buffer_list\"\n            });\n        }\n    }\n    \n    /*@CallerOwnsReturn*/ Caps gst_sample_get_caps(Sample sample);\n    /*@CallerOwnsReturn*/ Buffer gst_sample_get_buffer(Sample sample);\n    \n    void gst_sample_set_buffer(Sample sample, Buffer buffer);\n    void gst_sample_set_caps(Sample sample, Caps caps);\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstStructureAPI.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.Structure;\nimport org.freedesktop.gstreamer.lowlevel.GValueAPI.GValue;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\nimport org.freedesktop.gstreamer.lowlevel.annotations.FreeReturnValue;\n\nimport com.sun.jna.Pointer;\nimport com.sun.jna.ptr.IntByReference;\nimport com.sun.jna.ptr.PointerByReference;\n\n/**\n * GstStructure functions\n */\npublic interface GstStructureAPI extends com.sun.jna.Library {\n\tGstStructureAPI GSTSTRUCTURE_API = GstNative.load(GstStructureAPI.class);\n\n    GType gst_structure_get_type();\n\n    boolean gst_structure_get_int(Structure structure, String fieldname, IntByReference value);\n    boolean gst_structure_fixate_field_nearest_int(Structure structure, String field, int target);\n    @FreeReturnValue String gst_structure_to_string(Structure structure);\n    @CallerOwnsReturn Structure gst_structure_from_string(String data, PointerByReference end);\n    @CallerOwnsReturn Structure gst_structure_new_empty(String name);\n    @CallerOwnsReturn Structure gst_structure_new(String name, String firstField, Object... args);\n    @CallerOwnsReturn Pointer ptr_gst_structure_from_string(String data, PointerByReference end);\n    @CallerOwnsReturn Pointer ptr_gst_structure_new_empty(String name);\n    @CallerOwnsReturn Pointer ptr_gst_structure_new(String name, String firstField, Object... args);\n    @CallerOwnsReturn Structure gst_structure_copy(Structure src);\n    void gst_structure_remove_field(Structure structure, String fieldName);\n    void gst_structure_remove_fields(Structure structure, String... fieldNames);\n    void gst_structure_remove_all_fields(Structure structure);\n    \n    String gst_structure_get_name(Structure structure);\n    void gst_structure_set_name(Structure structure, String name);\n    boolean gst_structure_has_name(Structure structure, String name); \n    int gst_structure_n_fields(Structure structure);\n    String gst_structure_nth_field_name(Structure structure, int index);\n    boolean gst_structure_has_field(Structure structure, String fieldname);\n    boolean gst_structure_has_field_typed(Structure structure, String fieldname, GType type);\n    boolean gst_structure_is_equal(Structure structure1, Structure structure2);\n\n    /* utility functions */\n    boolean gst_structure_get_boolean(Structure structure, String fieldname, int[] value);\n    boolean gst_structure_get_int(Structure structure, String fieldname, int[] value);\n    boolean gst_structure_get_uint(Structure structure, String fieldname, int[] value);\n    boolean gst_structure_get_fourcc(Structure structure, String fieldname, int[] value);\n    boolean gst_structure_get_double(Structure structure, String fieldname, double[] value);\n    \n    boolean gst_structure_get_date(Structure structure, String fieldname, PointerByReference value);\n    boolean gst_structure_get_date(Structure structure, String fieldname, Pointer[] value);\n    //boolean gst_structure_get_clock_time(Structure structure, String fieldname, Gstlong *value);\n    \n    String gst_structure_get_string(Structure structure, String fieldname);\n    boolean gst_structure_get_enum(Structure structure, String fieldname, GType enumtype, int[] value);\n    boolean gst_structure_get_fraction(Structure structure, String fieldname,\n\t\t\t\t\t\t\t    int[] value_numerator,\n\t\t\t\t\t\t\t    int[] value_denominator);\n    GValue gst_structure_get_value(Structure structure, String fieldname);\n    void gst_structure_set(Structure structure, String fieldname, Object... args);\n    \n    void gst_structure_free(Pointer ptr);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstStructurePtr.java",
    "content": "/*\n * Copyright (c) 2020 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Native;\nimport com.sun.jna.Pointer;\n\n/**\n * GstStructure pointer\n */\npublic class GstStructurePtr extends GTypedPtr {\n    \n    public GstStructurePtr() {\n    }\n    \n    public GstStructurePtr(Pointer ptr) {\n        super(ptr);\n    }\n    \n    @Override\n    public GType getGType() {\n        // Quick getter for GType without allocation\n        if (Native.SIZE_T_SIZE == 8) {\n            return GType.valueOf(getPointer().getLong(0));\n        } else if (Native.SIZE_T_SIZE == 4) {\n            return GType.valueOf( ((long) getPointer().getInt(0)) & 0xffffffffL );\n        } else {\n            throw new IllegalStateException(\"SIZE_T size not supported: \" + Native.SIZE_T_SIZE);\n        }\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstTagAPI.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.TagFlag;\n\npublic interface GstTagAPI extends com.sun.jna.Library {\n\tGstTagAPI GSTTAG_API = GstNative.load(GstTagAPI.class);\n\n    boolean gst_tag_exists(String tag);\n    GType gst_tag_get_type(String tag);\n    String gst_tag_get_nick(String tag);\n    String gst_tag_get_description(String tag);\n    TagFlag gst_tag_get_flag(String tag);\n    boolean gst_tag_is_fixed(String tag);\n   \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstTagListAPI.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.TagList;\nimport org.freedesktop.gstreamer.TagMergeMode;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\n\nimport com.sun.jna.Pointer;\nimport com.sun.jna.ptr.PointerByReference;\n\n/**\n * GstTagList functions\n */\npublic interface GstTagListAPI extends com.sun.jna.Library {\n\tGstTagListAPI GSTTAGLIST_API = GstNative.load(GstTagListAPI.class);\n\n    interface TagForeachFunc extends GstCallback {\n        void callback(Pointer list, String tag, Pointer user_data);\n    }\n    interface TagMergeFunc extends GstCallback {\n        void callback(Pointer dest, Pointer src);\n    }\n    \n    @CallerOwnsReturn Pointer ptr_gst_tag_list_new_empty();\n    \n    void gst_tag_list_add(TagList list, TagMergeMode mode, String tag, Object... tags);\n    @CallerOwnsReturn TagList gst_tag_list_copy(TagList list);\n    @CallerOwnsReturn Pointer ptr_gst_tag_list_copy(TagList list);\n    boolean gst_tag_list_is_empty(TagList list);\n    void gst_tag_list_insert(TagList into, TagList from, TagMergeMode mode);\n\n    @CallerOwnsReturn TagList gst_tag_list_merge(TagList list1, TagList list2, TagMergeMode mode);\n    @CallerOwnsReturn Pointer ptr_gst_tag_list_merge(TagList list1, TagList list2, TagMergeMode mode);\n    int gst_tag_list_get_tag_size(TagList list, String tag);\n    void gst_tag_list_remove_tag(TagList list, TagList tag);\n    void gst_tag_list_foreach(TagList list, TagForeachFunc func, Pointer user_data);\n    \n    boolean gst_tag_list_get_char(TagList list, String tag, byte[] value);\n    boolean gst_tag_list_get_char_index(TagList list, String tag, int index, byte[] value);\n    boolean gst_tag_list_get_uchar(TagList list, String tag, byte[] value);\n    boolean gst_tag_list_get_uchar_index(TagList list, String tag, int index, byte[] value);\n    boolean gst_tag_list_get_boolean(TagList list, String tag, int[] value);\n    boolean gst_tag_list_get_boolean_index(TagList list, String tag, int index, int[] value);\n    boolean gst_tag_list_get_int(TagList list, String tag, int[] value);\n    boolean gst_tag_list_get_int_index(TagList list, String tag, int index, int[] value);\n    boolean gst_tag_list_get_uint(TagList list, String tag, int[] value);\n    boolean gst_tag_list_get_uint_index(TagList list, String tag, int index, int[] value);\n    boolean gst_tag_list_get_int64(TagList list, String tag, long[] value);\n    boolean gst_tag_list_get_int64_index(TagList list, String tag, int index, long[] value);\n    boolean gst_tag_list_get_double(TagList list, String tag, double[] value);\n    boolean gst_tag_list_get_double_index(TagList list, String tag, int index, double[] value);\n    boolean gst_tag_list_get_string(TagList list, String tag, PointerByReference value);\n    boolean gst_tag_list_get_string_index(TagList list, String tag, int index, PointerByReference value);\n    boolean gst_tag_list_get_string_index(TagList list, String tag, int index, Pointer[] value);\n    boolean gst_tag_list_get_date_index(TagList list, String tag, int index, PointerByReference value);\n    boolean gst_tag_list_get_date_index(TagList list, String tag, int index, Pointer[] value);\n    boolean gst_tag_list_get_date_time(TagList list, String tag, PointerByReference value);\n    boolean gst_tag_list_get_date_time_index(TagList list, String tag, int index, PointerByReference value);\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstTimedValueControlSourcePtr.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Pointer;\n\n/**\n * \n */\npublic class GstTimedValueControlSourcePtr extends GstControlSourcePtr {\n    \n    public GstTimedValueControlSourcePtr() {\n    }\n    \n    public GstTimedValueControlSourcePtr(Pointer ptr) {\n        super(ptr);\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstTriggerControlSourcePtr.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Pointer;\n\n/**\n * \n */\npublic class GstTriggerControlSourcePtr extends GstTimedValueControlSourcePtr {\n    \n    public GstTriggerControlSourcePtr() {\n    }\n    \n    public GstTriggerControlSourcePtr(Pointer ptr) {\n        super(ptr);\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstTypes.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2016 Christophe Lafolet\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2008 Andres Colubri\n * Copyright (c) 2007 Wayne Meissner\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\nimport org.freedesktop.gstreamer.glib.NativeObject;\nimport org.freedesktop.gstreamer.glib.NativeObject.TypeRegistration;\n\n/**\n *\n */\npublic class GstTypes {\n\n    private static final Logger logger = Logger.getLogger(GstTypes.class.getName());\n\n//    private static final Map<String, Class<? extends NativeObject>> gtypeNameMap\n//        = new ConcurrentHashMap<String, Class<? extends NativeObject>>();\n    private static final Map<String, TypeRegistration<?>> TYPES\n            = new ConcurrentHashMap<>();\n\n    private GstTypes() {\n    }\n\n    /**\n     * Register a class with its GType name\n     */\n//    public static void registerType(Class<? extends NativeObject> cls, String gTypeName) {\n//   \t\tgtypeNameMap.put(gTypeName, cls);\n//    }\n    public static void register(TypeRegistration<?> registration) {\n        TYPES.putIfAbsent(registration.getGTypeName(), registration);\n    }\n\n    /**\n     * Retrieve the class of a GType\n     *\n     * @param gType The type of Class\n     * @return The Class of the desired type or null.\n     */\n    public static final TypeRegistration<?> registrationFor(final GType gType) {\n        final String gTypeName = gType.getTypeName();\n\n        // Is this GType still registered in the map ? \n        TypeRegistration<?> reg = TYPES.get(gTypeName);\n        if (reg != null) {\n            return reg;\n        }\n\n        // Search for a parent class registration\n        GType type = gType.getParentType();\n        while (!type.equals(GType.OBJECT) && !type.equals(GType.POINTER) && !type.equals(GType.INVALID)) {\n            reg = TYPES.get(type.getTypeName());\n            if (reg != null) {\n                if (GstTypes.logger.isLoggable(Level.FINER)) {\n                    GstTypes.logger.finer(\"Found type of \" + gType + \" = \" + reg.getJavaType());\n                }\n\n                // The following line is an optimisation but not compatible with current implementation of GstTypes.typeFor()\n                // Uncomment the following line after refactoring of GstTypes.typeFor()\n                // gtypeNameMap.put(gTypeName, cls);\n                return reg;\n            }\n            type = type.getParentType();\n        }\n\n        // No registered class found for this gType\n        return null;\n    }\n    \n    public static final Class<? extends NativeObject> classFor(final GType gType) {\n    \tTypeRegistration<?> reg = registrationFor(gType);\n        return reg != null ? reg.getJavaType() : null;\n    }\n\n    //TODO : need refactoring to take into account derived class\n    public static final GType typeFor(Class<? extends NativeObject> cls) {\n        for (Map.Entry<String, TypeRegistration<?>> e : TYPES.entrySet()) {\n            if (e.getValue().getJavaType().equals(cls)) {\n                return GType.valueOf(e.getKey());\n            }\n        }\n        return GType.INVALID;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstValueAPI.java",
    "content": "/* \n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.lowlevel.GValueAPI.GValue;\n\n/**\n * GstValue functions\n */\npublic interface GstValueAPI extends com.sun.jna.Library {\n\tGstValueAPI GSTVALUE_API = GstNative.load(GstValueAPI.class);\n\n    GType gst_fourcc_get_type();\n    GType gst_int_range_get_type();\n    GType gst_double_range_get_type();\n    GType gst_fraction_range_get_type();\n    GType gst_value_list_get_type();\n    GType gst_fraction_get_type();\n    \n    int gst_value_get_fraction_numerator(GValue  value);\n    int gst_value_get_fraction_denominator(GValue value);\n    GValue gst_value_get_fraction_range_min(GValue value);\n    GValue gst_value_get_fraction_range_max(GValue value);\n    double gst_value_get_double_range_min(GValue value);\n    double gst_value_get_double_range_max(GValue value);\n    int gst_value_get_int_range_min(GValue value);\n    int gst_value_get_int_range_max(GValue value);\n    int gst_value_list_get_size(GValue value);\n    GValue gst_value_list_get_value(GValue value, int index);\n    \n    boolean gst_value_deserialize(GValue value, String src);\n    Pointer gst_value_serialize(GValue value);\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstVideoAPI.java",
    "content": "/*\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.Pad;\nimport org.freedesktop.gstreamer.lowlevel.GValueAPI.GValue;\n\nimport com.sun.jna.Library;\nimport com.sun.jna.Pointer;\nimport com.sun.jna.Structure;\nimport org.freedesktop.gstreamer.Gst;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\nimport org.freedesktop.gstreamer.video.VideoTimeCodeFlags;\n\npublic interface GstVideoAPI extends Library {\n\tpublic final static GstVideoAPI GSTVIDEO_API = GstNative.load(\"gstvideo\", GstVideoAPI.class);\n\n    @CallerOwnsReturn\n    Pointer gst_video_time_code_new_empty();\n    void gst_video_time_code_free(Pointer gstVideoTimeCode);\n    GValue gst_video_frame_rate(Pad pad);\n    boolean gst_video_get_size(Pad pad, int [] width, int [] height);\n\n    /* */\n    Pointer ptr_gst_video_event_new_downstream_force_key_unit(\n            long timestamp, long stream_time, long running_time,\n            boolean all_headers, int count);\n\n    Pointer ptr_gst_video_event_new_upstream_force_key_unit(\n            long running_time, boolean all_headers, int count);\n    \n    GType gst_video_time_code_meta_api_get_type();\n\n    GType gst_video_crop_meta_api_get_type();\n\n    GType gst_video_gl_texture_upload_meta_api_get_type();\n\n    GType gst_video_meta_api_get_type();\n\n    GType gst_video_region_of_interest_meta_api_get_type();\n\n//    MetaInfo gst_video_time_code_meta_get_info();\n\n\n    @Structure.FieldOrder({\"meta\", \"tc\"})\n    class GstVideoTimeCodeMetaStruct extends Structure {\n        public GstMetaAPI.GstMetaStruct.ByValue meta;\n        public GstVideoTimeCodeStruct.ByValue tc;\n\n        public GstVideoTimeCodeMetaStruct(Pointer p) {\n            super(p);\n            read();\n        }\n    }\n\n    @Structure.FieldOrder({\"config\", \"hours\", \"minutes\", \"seconds\", \"frames\", \"field_count\"})\n    @Gst.Since(minor = 10)\n    class GstVideoTimeCodeStruct extends Structure {\n        public static class ByValue extends GstVideoTimeCodeStruct implements Structure.ByValue {\n        }\n\n        public GstVideoTimeCodeConfigStruct.ByValue config;\n        public int hours;\n        public int minutes;\n        public int seconds;\n        public int frames;\n        public int field_count;\n\n        public GstVideoTimeCodeStruct() {\n        }\n\n        public GstVideoTimeCodeStruct(Pointer p) {\n            super(p);\n            read();\n        }\n    }\n    \n    @Structure.FieldOrder({\"fps_n\", \"fps_d\", \"flags\", \"latest_daily_jam\"})\n    @Gst.Since(minor = 10)\n    class GstVideoTimeCodeConfigStruct extends Structure {\n\n        public static class ByValue extends GstVideoTimeCodeConfigStruct implements Structure.ByValue {\n        }\n\n        public int fps_n;\n        public int fps_d;\n        public int flags;\n        public Pointer latest_daily_jam;\n\n        public GstVideoTimeCodeConfigStruct() {\n        }\n\n        public GstVideoTimeCodeConfigStruct(Pointer p) {\n            super(p);\n            read();\n        }\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstVideoOrientationAPI.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2009 Tamas Korodi <kotyo@zamba.fm>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.interfaces.VideoOrientation;\n\nimport com.sun.jna.Library;\n\npublic interface GstVideoOrientationAPI extends Library {\n\tGstVideoOrientationAPI GSTVIDEOORIENTATION_API = GstNative.load(\"gstvideo\", GstVideoOrientationAPI.class);\n\n\tGType gst_video_orientation_get_type();\n\n\t// @TODO need implementing to use pointers\n//\tboolean gst_video_orientation_get_hflip(VideoOrientation video_orientation, boolean flip);\n//\n//\tboolean gst_video_orientation_get_vflip(VideoOrientation video_orientation, boolean flip);\n//\n//\tboolean gst_video_orientation_get_hcenter(VideoOrientation video_orientation, int center);\n//\n//\tboolean gst_video_orientation_get_vcenter(VideoOrientation video_orientation, int center);\n\n\tboolean gst_video_orientation_set_hflip(VideoOrientation video_orientation, boolean flip);\n\n\tboolean gst_video_orientation_set_vflip(VideoOrientation video_orientation, boolean flip);\n\n\tboolean gst_video_orientation_set_hcenter(VideoOrientation video_orientation, int center);\n\n\tboolean gst_video_orientation_set_vcenter(VideoOrientation video_orientation, int center);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstVideoOverlayAPI.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2009 Tamas Korodi <kotyo@zamba.fm>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.message.Message;\nimport org.freedesktop.gstreamer.interfaces.VideoOverlay;\n\nimport com.sun.jna.Library;\nimport com.sun.jna.NativeLong;\nimport com.sun.jna.Pointer;\n\npublic interface GstVideoOverlayAPI extends Library {\n\tGstVideoOverlayAPI GSTVIDEOOVERLAY_API = GstNative.load(\"gstvideo\", GstVideoOverlayAPI.class);\n\n\tGType gst_video_overlay_get_type();\n\n\tvoid gst_video_overlay_set_window_handle(VideoOverlay overlay, Pointer xwindow_id);\n\n\tvoid gst_video_overlay_got_window_handle(VideoOverlay overlay, NativeLong xwindow_id);\n\n\tvoid gst_video_overlay_prepare_xwindow_id(VideoOverlay overlay);\n\n\tvoid gst_video_overlay_expose(VideoOverlay overlay);\n\n\tvoid gst_video_overlay_handle_events(VideoOverlay overlay, boolean handle_events);\n\t\n\tboolean\tgst_video_overlay_set_render_rectangle(VideoOverlay overlay, int x, int y, int width, int height);\n\n\tboolean gst_is_video_overlay_prepare_window_handle_message(Message message);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/GstWebRTCSessionDescriptionAPI.java",
    "content": "/*\n * Copyright (c) 2018 Vinicius Tona\n * Copyright (c) 2018 Antonio Morales\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport java.util.Arrays;\nimport java.util.List;\n\nimport org.freedesktop.gstreamer.webrtc.WebRTCSessionDescription;\nimport org.freedesktop.gstreamer.webrtc.WebRTCSDPType;\nimport org.freedesktop.gstreamer.SDPMessage;\nimport org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn;\nimport org.freedesktop.gstreamer.lowlevel.GValueAPI.GValueArray;\n\nimport com.sun.jna.Pointer;\n\n/**\n * GstWebRTCSessionDescription methods and structures\n * \n * @see https://github.com/GStreamer/gst-plugins-bad/blob/master/gst-libs/gst/webrtc/rtcsessiondescription.h\n * Available since GStreamer 1.14\n */\npublic interface GstWebRTCSessionDescriptionAPI extends com.sun.jna.Library {\n  GstWebRTCSessionDescriptionAPI GSTWEBRTCSESSIONDESCRIPTION_API =\n      GstNative.load(\"gstwebrtc\", GstWebRTCSessionDescriptionAPI.class);\n\n  public static final class WebRTCSessionDescriptionStruct extends com.sun.jna.Structure {\n    public volatile WebRTCSDPType type;\n    public volatile SDPMessage sdp;\n\n    public WebRTCSessionDescriptionStruct(final Pointer ptr) {\n      useMemory(ptr);\n    }\n\n    @Override\n    protected List<String> getFieldOrder() {\n      return Arrays.asList(new String[] { \"type\", \"sdp\" });\n    }\n  }\n\n  GType gst_webrtc_session_description_get_type();\n\n  @CallerOwnsReturn WebRTCSessionDescription gst_webrtc_session_description_new(WebRTCSDPType type, SDPMessage sdp);\n  @CallerOwnsReturn Pointer ptr_gst_webrtc_session_description_new(WebRTCSDPType type, SDPMessage sdp);\n\n  @CallerOwnsReturn WebRTCSessionDescription gst_webrtc_session_description_copy(WebRTCSessionDescription src);\n  @CallerOwnsReturn Pointer ptr_gst_webrtc_session_description_copy(WebRTCSessionDescription src);\n\n  void gst_webrtc_session_description_free(Pointer desc);\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/IntPtr.java",
    "content": "/* \n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport com.sun.jna.Native;\n\n@SuppressWarnings(\"serial\")\npublic class IntPtr extends Number {\n    public final Number value;\n    public IntPtr(int value) {\n        this.value = Native.POINTER_SIZE == 8 ? new Long(value) : new Integer(value);\n    }\n    \n    public String toString() {        \n        return Integer.toHexString(intValue());\n    }\n\n    public int intValue() {\n        return value.intValue();\n    }\n    \n    public long longValue() {\n        return value.longValue();\n    }\n\n    public float floatValue() {\n        return value.floatValue();        \n    }\n\n    public double doubleValue() {\n        return value.doubleValue();        \n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/MainLoop.java",
    "content": "/* \n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport static org.freedesktop.gstreamer.lowlevel.GlibAPI.GLIB_API;\n\nimport java.util.ArrayList;\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.concurrent.ExecutionException;\nimport java.util.concurrent.FutureTask;\n\nimport org.freedesktop.gstreamer.Gst;\n\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.glib.GMainContext;\nimport org.freedesktop.gstreamer.glib.GSource;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.glib.RefCountedObject;\n\n/**\n * The GLib main loop.\n */\npublic class MainLoop extends RefCountedObject {\n\n    private static final List<Runnable> bgTasks = new LinkedList<Runnable>();\n\n    private Thread bgThread;\n\n    /**\n     * Creates a new instance of {@code MainLoop}\n     *\n     * <p>\n     * This will create a new main loop on the default gstreamer main context.\n     *\n     */\n    public MainLoop() {\n        this(Natives.initializer(GLIB_API.g_main_loop_new(Gst.getMainContext(), false)));\n    }\n\n    public MainLoop(GMainContext ctx) {\n        this(Natives.initializer(GLIB_API.g_main_loop_new(ctx, false)));\n    }\n\n    /**\n     * Creates a new instance of {@code MainLoop}\n     *\n     * <p>\n     * This variant is used internally.\n     *\n     * @param init internal initialization data.\n     */\n    public MainLoop(Initializer init) {\n        super(new Handle(init.ptr, init.ownsHandle), init.needRef);\n    }\n\n    /**\n     * Instructs a main loop to stop processing and return from {@link #run}.\n     */\n    public void quit() {\n        invokeLater(new Runnable() {\n            public void run() {\n                GLIB_API.g_main_loop_quit(MainLoop.this);\n            }\n        });\n    }\n\n    /**\n     * Enter a loop, processing all events.\n     * <p>\n     * The loop will continue processing events until {@link #quit} is called.\n     */\n    public void run() {\n        GLIB_API.g_main_loop_run(this);\n    }\n\n    /**\n     * Returns whether this main loop is currently processing or not.\n     *\n     * @return <tt>true</tt> if the main loop is currently being run.\n     */\n    public boolean isRunning() {\n        return GLIB_API.g_main_loop_is_running(this);\n    }\n\n    /**\n     * Gets the main context for this main loop.\n     *\n     * @return a main context.\n     */\n    public GMainContext getMainContext() {\n        return GLIB_API.g_main_loop_get_context(this);\n    }\n\n    /**\n     * Runs the main loop in a background thread.\n     */\n    public void startInBackground() {\n        bgThread = new java.lang.Thread(new Runnable() {\n\n            public void run() {\n                MainLoop.this.run();\n            }\n        });\n        bgThread.setDaemon(true);\n        bgThread.setName(\"gmainloop\");\n        bgThread.start();\n    }\n\n    /**\n     * Invokes a task on the main loop thread.\n     * <p>\n     * This method will wait until the task has completed before returning.\n     *\n     * @param r the task to invoke.\n     */\n    public void invokeAndWait(Runnable r) {\n        FutureTask<Object> task = new FutureTask<Object>(r, null);\n        invokeLater(task);\n        try {\n            task.get();\n        } catch (InterruptedException ex) {\n            throw new RuntimeException(ex.getCause());\n        } catch (ExecutionException ex) {\n            throw new RuntimeException(ex.getCause());\n        }\n    }\n    private static final GlibAPI.GSourceFunc bgCallback = new GlibAPI.GSourceFunc() {\n        public boolean callback(Pointer source) {\n            //            System.out.println(\"Running g_idle callbacks\");\n            List<Runnable> tasks = new ArrayList<Runnable>();\n            synchronized (bgTasks) {\n                tasks.addAll(bgTasks);\n                bgTasks.clear();\n            }\n            for (Runnable r : tasks) {\n                r.run();\n            }\n            GLIB_API.g_source_unref(source);\n            return false;\n        }\n    };\n\n    /**\n     * Invokes a task on the main loop thread.\n     * <p>\n     * This method returns immediately, without waiting for the task to\n     * complete.\n     *\n     * @param r the task to invoke.\n     */\n    public void invokeLater(final Runnable r) {\n        //        System.out.println(\"Scheduling idle callbacks\");\n        synchronized (bgTasks) {\n            boolean empty = bgTasks.isEmpty();\n            bgTasks.add(r);\n            // Only trigger the callback if there were no existing elements in the list\n            // otherwise it is already triggered\n            if (empty) {\n                GSource source = GLIB_API.g_idle_source_new();\n                GLIB_API.g_source_set_callback(source, bgCallback, source, null);\n                source.attach(Gst.getMainContext());\n                source.disown(); // gets destroyed in the callback\n            }\n        }\n    }\n\n    private final static class Handle extends RefCountedObject.Handle {\n\n        public Handle(GPointer ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n\n        @Override\n        protected void disposeNativeHandle(GPointer ptr) {\n            GLIB_API.g_main_loop_unref(ptr);\n        }\n\n        @Override\n        protected void ref() {\n            GLIB_API.g_main_loop_ref(getPointer());\n        }\n\n        @Override\n        protected void unref() {\n            GLIB_API.g_main_loop_unref(getPointer());\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/README",
    "content": "lowlevel cleanup log\n\n\nstructures in the following classes were aligned to 1.8:\n(https://cgit.freedesktop.org/gstreamer/gstreamer/tree/?h=1.8)\n\n- BaseSinkAPI\n- BaseSrcAPI\n- BaseTransformAPI\n- GstAPI\n- GstBufferAPI\n- GstBufferPoolAPI\n- GstControlSourceAPI\n- GstControllerAPI - removed\n- GstElementAPI\n- GstEvent\n- GstObject\n- GstPadProbeInfo\n- GstQueryAPI\n- GstSampleAPI"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/ReferenceManager.java",
    "content": "/* \n * Copyright (C) 2008 Wayne Meissner\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport java.lang.ref.ReferenceQueue;\nimport java.lang.ref.WeakReference;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\nimport org.freedesktop.gstreamer.glib.RefCountedObject;\n\n/**\n * Manages keep alive links from one object to another.\n */\npublic class ReferenceManager {\n    private ReferenceManager() {}\n    /**\n     * Adds a link from <tt>ref</tt> to <tt>target</tt> that keeps target alive\n     * whilst <tt>ref</tt> is alive.\n     * \n     * @param ref\n     * @param target\n     */\n    public static <T extends Object> T addKeepAliveReference(T ref, RefCountedObject target) {\n        if (ref != null) {\n            StaticData.map.put(new WeakReference<Object>(ref, StaticData.queue), target);\n        }\n        return ref;\n    }\n    \n    /**\n     * Holds static data for lazy loading.\n     */\n    private static class StaticData {\n        private static final Map<Object, Object> map = new ConcurrentHashMap<Object, Object>();\n        private static final ReferenceQueue<Object> queue = new ReferenceQueue<Object>();\n        static {\n            Thread t = new Thread(new Runnable() {\n\n                public void run() {\n                    while (true) {\n                        try {\n                            map.remove(queue.remove());\n                        } catch (InterruptedException ex) {\n                            break;\n                        } catch (Throwable ex) {\n                            // Don't break out of the loop for any other reason\n                            continue;\n                        }\n                    }\n                }\n            });\n            t.setName(\"Reference reaper\");\n            t.setDaemon(true);\n            t.start();\n        }\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/annotations/CallerOwnsReturn.java",
    "content": "/* \n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel.annotations;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Indicates that the returned value is owned by the method caller, so appropriate\n * action should be taken when the object is garbage collected.\n */\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.METHOD)\npublic @interface CallerOwnsReturn {\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/annotations/Const.java",
    "content": "/* \n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel.annotations;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n *\n * @author wayne\n */\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ElementType.PARAMETER, ElementType.METHOD})\npublic @interface Const {\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/annotations/ConstField.java",
    "content": "/* \n * Copyright (C) 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel.annotations;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n *\n * @author wayne\n */\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.FIELD)\npublic @interface ConstField {\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/annotations/ConstReturn.java",
    "content": "/* \n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel.annotations;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n *\n * @author wayne\n */\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.METHOD)\npublic @interface ConstReturn {\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/annotations/DefaultEnumValue.java",
    "content": "/* \n * Copyright (C) 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel.annotations;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Used to flag the Enum value to use for converting from a native value,\n * when no exact match is found.\n */\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.FIELD)\npublic @interface DefaultEnumValue {\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/annotations/FreeReturnValue.java",
    "content": "/* \n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel.annotations;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n *\n * @author wayne\n */\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.METHOD)\npublic @interface FreeReturnValue {\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/annotations/HasSubtype.java",
    "content": "/* \n * Copyright (c) 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel.annotations;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.TYPE)\npublic @interface HasSubtype {\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/annotations/IncRef.java",
    "content": "/* \n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel.annotations;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Signal that the Handle parameter's refcount should be incremented\n */\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.PARAMETER)\n\npublic @interface IncRef {\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/lowlevel/annotations/Invalidate.java",
    "content": "/* \n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel.annotations;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Signal that the Handle parameter should be invalidated (not used after this call)\n */\n@Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.PARAMETER)\npublic @interface Invalidate {\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/message/BufferingMessage.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.message;\n\nimport org.freedesktop.gstreamer.GstObject;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API;\n\n/**\n * This message can be posted by an element that\n * needs to buffer data before it can continue processing. {@code percent} should be a\n * value between 0 and 100. A value of 100 means that the buffering completed.\n * <p>\n * See upstream documentation\n * at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-buffering\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-buffering</a>\n * <p>\n * When <tt>percent</tt> is &lt; 100 the application should PAUSE a PLAYING pipeline. When\n * <tt>percent</tt> is 100, the application can set the pipeline (back) to PLAYING.\n * The application must be prepared to receive BUFFERING messages in the\n * PREROLLING state and may only set the pipeline to PLAYING after receiving a\n * message with <tt>percent</tt> set to 100, which can happen after the pipeline\n * completed prerolling. \n */\npublic class BufferingMessage extends Message {\n\n    /**\n     * Creates a new Buffering message.\n     * @param init internal initialization data.\n     */\n    BufferingMessage(Initializer init) {\n        super(init);\n    }\n    \n    /**\n     * Creates a new Buffering message.\n     * @param src The object originating the message.\n     * @param percent The buffering percent\n     */\n    public BufferingMessage(GstObject src, int percent) {\n        this(Natives.initializer(GSTMESSAGE_API.ptr_gst_message_new_buffering(src, percent)));\n    }\n    \n    /**\n     * Gets the buffering percentage.\n     * \n     * @return the percentage that is being buffered.\n     */\n    public int getPercent() {\n        int[] percent = { 0 };\n        GSTMESSAGE_API.gst_message_parse_buffering(this, percent);\n        return percent[0];\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/message/DurationChangedMessage.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.message;\n\nimport org.freedesktop.gstreamer.GstObject;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API;\n\n/**\n * A duration changed message.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-duration-changed\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-duration-changed</a>\n * <p>\n * This message is posted by elements that know the duration of a stream when\n * the duration changes. This message is received by bins and is used to\n * calculate the total duration of a pipeline.\n */\npublic class DurationChangedMessage extends Message {\n\n    /**\n     * Creates a new DurationChanged message.\n     *\n     * @param init internal initialization data.\n     */\n    DurationChangedMessage(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Creates a new DurationChanged Message\n     *\n     * @param src The object originating the message.\n     */\n    public DurationChangedMessage(GstObject src) {\n        this(Natives.initializer(GSTMESSAGE_API.ptr_gst_message_new_duration_changed(src)));\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/message/EOSMessage.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.message;\n\nimport org.freedesktop.gstreamer.Bin;\nimport org.freedesktop.gstreamer.GstObject;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API;\n\n/**\n * An End-of-Stream Message.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-eos\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-eos</a>\n * <p>\n * This message is generated and posted in the sink elements of a {@link Bin}.\n * The bin will only forward the EOS message to the application if all sinks\n * have posted an EOS message.\n */\npublic class EOSMessage extends Message {\n\n    /**\n     * Creates a new eos message.\n     *\n     * @param init internal initialization data.\n     */\n    EOSMessage(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Creates a new eos message.\n     *\n     * @param src The object originating the message.\n     */\n    public EOSMessage(GstObject src) {\n        this(Natives.initializer(GSTMESSAGE_API.ptr_gst_message_new_eos(src)));\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/message/ErrorMessage.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.message;\n\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GErrorStruct;\nimport static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API;\n\n/**\n * This message is posted by element when a fatal event occurs.  \n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-error\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-error</a>\n * <p>\n * The pipeline will probably (partially) stop. The application\n * receiving this message should stop the pipeline.\n */\npublic class ErrorMessage extends GErrorMessage {\n\n    /**\n     * Creates a new error message.\n     * \n     * @param init internal initialization data.\n     */\n    ErrorMessage(Initializer init) {\n        super(init);\n    }\n    \n    /**\n     * Retrieves the GError structure contained in this message.\n     * \n     * @return the GError contained in this message.\n     */\n    @Override\n    GErrorStruct parseMessage() {\n        GErrorStruct[] err = { null };\n        GSTMESSAGE_API.gst_message_parse_error(this, err, null);\n        return err[0];\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/message/GErrorMessage.java",
    "content": "/* \n * Copyright (C) 2025 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n\npackage org.freedesktop.gstreamer.message;\n\nimport org.freedesktop.gstreamer.lowlevel.GstAPI;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GErrorStruct;\nimport static org.freedesktop.gstreamer.lowlevel.GlibAPI.GLIB_API;\n\n/**\n * Package private base class for ERROR, WARNING and INFO messages.\n */\nabstract class GErrorMessage extends Message {\n    \n    /**\n     * Creates a new GError message.\n     * @param init internal initialization data.\n     */\n    GErrorMessage(Initializer init) {\n        super(init);\n    }\n    \n    abstract GstAPI.GErrorStruct parseMessage();\n    \n    /**\n     * Gets the error code from this message.\n     * \n     * @return the error code.\n     */\n    public int getCode() {\n        GErrorStruct err = parseMessage();\n        if (err == null) {\n            throw new NullPointerException(\"Could not parse message\");\n        }\n        int code = err.code;\n        GLIB_API.g_error_free(err.getPointer());\n        return code;\n    }\n    \n    /**\n     * Gets the message contained in this message.\n     * \n     * @return the message contained in this message.\n     */\n    public String getMessage() {\n        GErrorStruct err = parseMessage();\n        if (err == null) {\n            throw new NullPointerException(\"Could not parse message\");\n        }\n        String message = err.getMessage();\n        GLIB_API.g_error_free(err.getPointer());\n        return message;\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/message/InfoMessage.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.message;\n\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GErrorStruct;\nimport static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API;\n\n/**\n * This message is posted by element to provide information to the application.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-info\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-info</a>\n * <p>\n */\npublic class InfoMessage extends GErrorMessage {\n\n    /**\n     * Creates a new info message.\n     *\n     * @param init internal initialization data.\n     */\n    InfoMessage(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Retrieves the GError structure contained in this message.\n     *\n     * @return the GError contained in this message.\n     */\n    @Override\n    GErrorStruct parseMessage() {\n        GErrorStruct[] err = {null};\n        GSTMESSAGE_API.gst_message_parse_info(this, err, null);\n        return err[0];\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/message/LatencyMessage.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.message;\n\nimport org.freedesktop.gstreamer.GstObject;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API;\n\n/**\n * Message posted by elements when their latency requirements have changed.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-latency\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-latency</a>\n * <p>\n */\npublic class LatencyMessage extends Message {\n\n    /**\n     * Creates a new Latency message.\n     *\n     * @param init internal initialization data.\n     */\n    LatencyMessage(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Creates a new Latency message.\n     *\n     * @param source the object originating the message.\n     */\n    public LatencyMessage(GstObject source) {\n        this(Natives.initializer(GSTMESSAGE_API.ptr_gst_message_new_latency(source)));\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/message/Message.java",
    "content": "/* \n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2007, 2008 Wayne Meissner\n * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.message;\n\nimport java.util.EnumMap;\nimport java.util.Map;\nimport java.util.function.Function;\nimport java.util.stream.Stream;\nimport org.freedesktop.gstreamer.GstObject;\nimport org.freedesktop.gstreamer.MiniObject;\nimport org.freedesktop.gstreamer.Structure;\nimport org.freedesktop.gstreamer.glib.NativeEnum;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GstMessagePtr;\nimport org.freedesktop.gstreamer.lowlevel.ReferenceManager;\nimport org.freedesktop.gstreamer.lowlevel.annotations.HasSubtype;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API;\n\n/**\n * Lightweight objects to signal the occurrence of pipeline events.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html</a>\n * <p>\n * Messages are implemented as a subclass of {@link MiniObject} with a generic\n * {@link Structure} as the content. This allows for writing custom messages\n * without requiring an API change while allowing a wide range of different\n * types of messages.\n * <p>\n * Messages are posted by objects in the pipeline and are passed to the\n * application using the {@link Bus}.\n *\n * The basic use pattern of posting a message on a Bus is as follows:\n *\n * <example>\n * <title>Posting a Message</title>\n * <code>\n *    bus.post(new EOSMessage(source));\n * </code>\n * </example>\n *\n * An {@link Element} usually posts messages on the bus provided by the parent\n * container using {@link Element#postMessage postMessage()}.\n */\n@HasSubtype\npublic class Message extends MiniObject {\n\n    public static final String GTYPE_NAME = \"GstMessage\";\n\n    private static final Map<MessageType, Function<Initializer, Message>> TYPE_MAP\n            = new EnumMap<>(MessageType.class);\n\n    static {\n        TYPE_MAP.put(MessageType.EOS, EOSMessage::new);\n        TYPE_MAP.put(MessageType.ERROR, ErrorMessage::new);\n        TYPE_MAP.put(MessageType.BUFFERING, BufferingMessage::new);\n        TYPE_MAP.put(MessageType.DURATION_CHANGED, DurationChangedMessage::new);\n        TYPE_MAP.put(MessageType.INFO, InfoMessage::new);\n        TYPE_MAP.put(MessageType.LATENCY, LatencyMessage::new);\n        TYPE_MAP.put(MessageType.SEGMENT_DONE, SegmentDoneMessage::new);\n        TYPE_MAP.put(MessageType.STATE_CHANGED, StateChangedMessage::new);\n        TYPE_MAP.put(MessageType.TAG, TagMessage::new);\n        TYPE_MAP.put(MessageType.WARNING, WarningMessage::new);\n        TYPE_MAP.put(MessageType.NEED_CONTEXT, NeedContextMessage::new);\n    }\n\n    private final Handle handle;\n\n    /**\n     * Creates a new instance of Message.\n     *\n     * @param init internal initialization data.\n     */\n    Message(Initializer init) {\n        this(new Handle(init.ptr.as(GstMessagePtr.class, GstMessagePtr::new), init.ownsHandle), init.needRef);\n    }\n\n    Message(Handle handle, boolean needRef) {\n        super(handle, needRef);\n        this.handle = handle;\n    }\n\n    /**\n     * Gets the Element that posted this message.\n     *\n     * @return the element that posted the message.\n     */\n    public GstObject getSource() {\n        return Natives.objectFor(handle.getPointer().getSource(), GstObject.class, true, true);\n    }\n\n    /**\n     * Gets the structure containing the data in this message.\n     *\n     * @return a structure.\n     */\n    public Structure getStructure() {\n        return ReferenceManager.addKeepAliveReference(GSTMESSAGE_API.gst_message_get_structure(this), this);\n    }\n\n    /**\n     * Gets the type of this message.\n     *\n     * @return the message type.\n     */\n    public MessageType getType() {\n        return NativeEnum.fromInt(MessageType.class, MessageType.UNKNOWN,\n                handle.getPointer().getMessageType());\n    }\n\n    private static Message create(Initializer init) {\n        MessageType type = NativeEnum.fromInt(MessageType.class,\n                MessageType.UNKNOWN,\n                init.ptr.as(GstMessagePtr.class, GstMessagePtr::new).getMessageType()\n        );\n        return TYPE_MAP.getOrDefault(type, Message::new).apply(init);\n    }\n\n    public static class Types implements TypeProvider {\n\n        @Override\n        public Stream<TypeRegistration<?>> types() {\n            return Stream.of(\n                    Natives.registration(Message.class, GTYPE_NAME, Message::create)\n            );\n        }\n\n    }\n\n    static class Handle extends MiniObject.Handle {\n\n        Handle(GstMessagePtr ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n\n        @Override\n        protected GstMessagePtr getPointer() {\n            return (GstMessagePtr) super.getPointer();\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/message/MessageType.java",
    "content": "/* \n * Copyright (C) 2020 Neil C Smith\n * Copyright (C) 2009 Levente Farkas\n * Copyright (C) 2008 Wayne Meissner\n * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.message;\n\nimport org.freedesktop.gstreamer.Gst;\nimport org.freedesktop.gstreamer.device.Device;\nimport org.freedesktop.gstreamer.device.DeviceProvider;\nimport org.freedesktop.gstreamer.glib.NativeEnum;\n\n/**\n * The different message types that are available.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#GstMessageType\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#GstMessageType</a>\n * <p>\n */\n// use NativeEnum not NativeFlags - from upstream definition\n// FIXME: 2.0: Make it NOT flags, just a regular 1,2,3,4.. enumeration\npublic enum MessageType implements NativeEnum<MessageType> {\n    /**\n     * An undefined message\n     */\n    UNKNOWN(0),\n    /**\n     * end-of-stream reached in a pipeline. The application will only receive\n     * this message in the PLAYING state and every time it sets a pipeline to\n     * PLAYING that is in the EOS state. The application can perform a flushing\n     * seek in the pipeline, which will undo the EOS state again.\n     */\n    EOS(1 << 0),\n    /**\n     * An error occurred. When the application receives an error message it\n     * should stop playback of the pipeline and not assume that more data will\n     * be played.\n     */\n    ERROR(1 << 1),\n    /**\n     * A warning occurred.\n     */\n    WARNING(1 << 2),\n    /**\n     * An info message occurred.\n     */\n    INFO(1 << 3),\n    /**\n     * A tag was found.\n     */\n    TAG(1 << 4),\n    /**\n     * The pipeline is buffering. When the application receives a buffering\n     * message in the PLAYING state for a non-live pipeline it must PAUSE the\n     * pipeline until the buffering completes, when the percentage field in the\n     * message is 100%. For live pipelines, no action must be performed and the\n     * buffering percentage can be used to inform the user about the progress.\n     */\n    BUFFERING(1 << 5),\n    /**\n     * A state change happened\n     */\n    STATE_CHANGED(1 << 6),\n    /**\n     * an element changed state in a streaming thread. This message is\n     * deprecated.\n     */\n    STATE_DIRTY(1 << 7),\n    /**\n     * a framestep finished. This message is not yet implemented.\n     */\n    STEP_DONE(1 << 8),\n    /**\n     * an element notifies its capability of providing a clock. This message is\n     * used internally and never forwarded to the application.\n     */\n    CLOCK_PROVIDE(1 << 9),\n    /**\n     * The current clock as selected by the pipeline became unusable. The\n     * pipeline will select a new clock on the next PLAYING state change.\n     */\n    CLOCK_LOST(1 << 10),\n    /**\n     * A new clock was selected in the pipeline.\n     */\n    NEW_CLOCK(1 << 11),\n    /**\n     * The structure of the pipeline changed. Not implemented yet.\n     */\n    STRUCTURE_CHANGE(1 << 12),\n    /**\n     * Status about a stream, emitted when it starts, stops, errors, etc.. Not\n     * implemented yet.\n     */\n    STREAM_STATUS(1 << 13),\n    /**\n     * Message posted by the application, possibly via an application-specific\n     * element.\n     */\n    APPLICATION(1 << 14),\n    /**\n     * Element specific message, see the specific element's documentation\n     */\n    ELEMENT(1 << 15),\n    /**\n     * Pipeline started playback of a segment. This message is used internally\n     * and never forwarded to the application.\n     */\n    SEGMENT_START(1 << 16),\n    /**\n     * Pipeline completed playback of a segment. This message is forwarded to\n     * the application after all elements that posted {@link #SEGMENT_START}\n     * have posted a SEGMENT_DONE message.\n     */\n    SEGMENT_DONE(1 << 17),\n    /**\n     * The duration of a pipeline changed. The application can get the new\n     * duration with a duration query.\n     */\n    DURATION_CHANGED(1 << 18),\n    /**\n     * Posted by elements when their latency changes. The pipeline will\n     * calculate and distribute a new latency. Since: 0.10.12\n     */\n    LATENCY(1 << 19),\n    /**\n     * Posted by elements when they start an ASYNC state change. This message is\n     * not forwarded to the application but is used internally. Since: 0.10.13.\n     */\n    ASYNC_START(1 << 20),\n    /**\n     * Posted by elements when they complete an ASYNC state change. The\n     * application will only receive this message from the toplevel pipeline.\n     * Since: 0.10.13\n     */\n    ASYNC_DONE(1 << 21),\n    /**\n     * Posted by elements when they want the pipeline to change state. This\n     * message is a suggestion to the application which can decide to perform\n     * the state change on (part of) the pipeline. Since: 0.10.23.\n     */\n    REQUEST_STATE(1 << 22),\n    /**\n     * A stepping operation was started.\n     */\n    STEP_START(1 << 23),\n    /**\n     * A buffer was dropped or an element changed its processing strategy for\n     * Quality of Service reasons.\n     */\n    QOS(1 << 24),\n    /**\n     * A progress message. Since: 0.10.33\n     */\n    PROGRESS(1 << 25),\n    /**\n     * A new table of contents (TOC) was found or previously found TOC was\n     * updated. Since: 0.10.37\n     */\n    TOC(1 << 26),\n    /**\n     * Message to request resetting the pipeline's running time from the\n     * pipeline. This is an internal message which applications will likely\n     * never receive.\n     */\n    RESET_TIME(1 << 27),\n    /**\n     * Message indicating start of a new stream. Useful e.g. when using playbin\n     * in gapless playback mode, to get notified when the next title actually\n     * starts playing (which will be some time after the URI for the next title\n     * has been set).\n     */\n    STREAM_START(1 << 28),\n    /**\n     * Message indicating that an element wants a specific context (Since 1.2)\n     */\n    NEED_CONTEXT(1 << 29),\n    /**\n     * Message indicating that an element created a context (Since 1.2)\n     */\n    HAVE_CONTEXT(1 << 30),\n    /**\n     * Message is an extended message type (see below). These extended message\n     * IDs can't be used directly with mask-based API like gst_bus_poll() or\n     * gst_bus_timed_pop_filtered(), but you can still filter for\n     * GST_MESSAGE_EXTENDED and then check the result for the specific type.\n     * (Since 1.4)\n     */\n    EXTENDED(1 << 31),\n    /**\n     * Message indicating a #GstDevice was added to a #GstDeviceProvider (Since\n     * 1.4)\n     */\n    DEVICE_ADDED(EXTENDED.intValue() + 1),\n    /**\n     * Message indicating a #GstDevice was removed from a #GstDeviceProvider\n     * (Since 1.4)\n     */\n    DEVICE_REMOVED(EXTENDED.intValue() + 2),\n    /**\n     * Message indicating a {@link GObject} property has changed (Since 1.10)\n     */\n    @Gst.Since(minor = 10)\n    PROPERTY_NOTIFY(EXTENDED.intValue() + 3),\n    /**\n     * Message indicating a new {@link GstStreamCollection} is available (Since\n     * 1.10)\n     */\n    @Gst.Since(minor = 10)\n    STREAM_COLLECTION(EXTENDED.intValue() + 4),\n    /**\n     * Message indicating the active selection of {@link GstStreams} has changed\n     * (Since 1.10)\n     */\n    @Gst.Since(minor = 10)\n    STREAMS_SELECTED(EXTENDED.intValue() + 5),\n    /**\n     * Message indicating to request the application to try to play the given\n     * URL(s). Useful if for example a HTTP 302/303 response is received with a\n     * non-HTTP URL inside. (Since 1.10)\n     */\n    @Gst.Since(minor = 10)\n    REDIRECT(EXTENDED.intValue() + 6),\n    /**\n     * Message indicating a {@link Device} was changed by a\n     * {@link DeviceProvider} (Since 1.16)\n     */\n    @Gst.Since(minor = 16)\n    DEVICE_CHANGED(EXTENDED.intValue() + 7),\n    /**\n     * Message sent by elements to request the running time from the pipeline\n     * when an instant rate change should be applied (which may be in the past\n     * when the answer arrives). (Since 1.18)\n     */\n    @Gst.Since(minor = 18)\n    INSTANT_RATE_REQUEST(EXTENDED.intValue() + 8),\n    /**\n     * mask for all of the above messages.\n     */\n    ANY(~0);\n\n    private final int type;\n\n    private MessageType(int type) {\n        this.type = type;\n    }\n\n    /**\n     * Gets the native integer value for this type.\n     *\n     * @return the native gstreamer value.\n     */\n    @Override\n    public int intValue() {\n        return type;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/message/NeedContextMessage.java",
    "content": "/* \n *\n * Copyright (c) 2019 Christophe Lafolet\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.message;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API;\n\nimport org.freedesktop.gstreamer.GstObject;\nimport org.freedesktop.gstreamer.glib.Natives;\n\n/**\n * Message indicating that an element wants a specific context.\n */\npublic class NeedContextMessage extends Message {\n\n    /**\n     * Creates a new Need-Context message.\n     * \n     * @param init internal initialization data.\n     */\n    NeedContextMessage(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Creates a new Need-Context message.\n     *\n     * @param src the object originating the message.\n     */\n    public NeedContextMessage(GstObject src, String context_type) {\n        this(Natives.initializer(GSTMESSAGE_API.ptr_gst_message_new_need_context(src, context_type)));\n    }\n\n    /**\n     * Gets the context type contained in this message.\n     * \n     * @return the context type.\n     */\n    public String getContextType() {\n        String context_type[] = new String[1];\n        boolean isOk = GSTMESSAGE_API.gst_message_parse_context_type(this, context_type);\n        return isOk ? context_type[0] : null;\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/message/SegmentDoneMessage.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.message;\n\nimport org.freedesktop.gstreamer.Format;\nimport org.freedesktop.gstreamer.GstObject;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API;\n\n/**\n * This message is posted by elements that finish playback of a segment as a \n * result of a segment seek. \n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-segment-done\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-segment-done</a>\n * <p>\n * This message is received by the application after all elements that posted a segment_start\n * have posted the segment_done.\n */\npublic class SegmentDoneMessage extends Message {\n\n    /**\n     * Creates a new segment-done message.\n     * \n     * @param init internal initialization data.\n     */\n    SegmentDoneMessage(Initializer init) {\n        super(init);\n    }\n    \n    /**\n     * Creates a new segment done message.\n     * \n     * @param src the object originating the message.\n     * @param format the format of the position being done\n     * @param position the position of the segment being done\n     */\n    public SegmentDoneMessage(GstObject src, Format format, long position) {\n        this(Natives.initializer(GSTMESSAGE_API.ptr_gst_message_new_segment_done(src, format, position)));\n    }\n    \n    /**\n     * Gets the format of the position in this message.\n     * \n     * @return the format of the position.\n     */\n    public Format getFormat() {\n        Format[] format = new Format[1];\n        GSTMESSAGE_API.gst_message_parse_segment_done(this, format, null);\n        return format[0];\n    }\n    \n    /**\n     * Gets the position of the segment that is done.\n     * \n     * @return the position.\n     */\n    public long getPosition() {\n        long[] position = { 0 };\n        GSTMESSAGE_API.gst_message_parse_segment_done(this, null, position);\n        return position[0];\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/message/StateChangedMessage.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.message;\n\nimport org.freedesktop.gstreamer.GstObject;\nimport org.freedesktop.gstreamer.State;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API;\n\n/**\n * A state change message. \n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-state-changed\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-state-changed</a>\n * <p>\n * This message is posted whenever an element changes its state.\n */\npublic class StateChangedMessage extends Message {\n\n    /**\n     * Creates a new Buffering message.\n     * @param init internal initialization data.\n     */\n    StateChangedMessage(Initializer init) {\n        super(init);\n    }\n    \n    /**\n     * Creates a new state-changed message.\n     *\n     * @param src the source object emitting this message.\n     * @param old the previous state.\n     * @param current the new (current) state.\n     * @param pending the pending (target) state.\n     */\n    public StateChangedMessage(GstObject src, State old, State current, State pending) {\n        super(Natives.initializer(GSTMESSAGE_API.ptr_gst_message_new_state_changed(src, old, current, pending)));\n    }\n    \n    /**\n     * Gets the previous state.\n     * \n     * @return the previous state.\n     */\n    public State getOldState() {\n        State[] state = new State[1];\n        GSTMESSAGE_API.gst_message_parse_state_changed(this, state, null, null);\n        return state[0];\n    }\n    \n    /**\n     * Gets the new (current) state.\n     * \n     * @return the new state.\n     */\n    public State getNewState() {\n        State[] state = new State[1];\n        GSTMESSAGE_API.gst_message_parse_state_changed(this, null, state, null);\n        return state[0];\n    }\n    \n    /**\n     * Gets the pending (target) state.\n     * \n     * @return the pending state.\n     */\n    public State getPendingState() {\n        State[] state = new State[1];\n        GSTMESSAGE_API.gst_message_parse_state_changed(this, null, null, state);\n        return state[0];\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/message/TagMessage.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.message;\n\nimport org.freedesktop.gstreamer.GstObject;\nimport org.freedesktop.gstreamer.TagList;\nimport com.sun.jna.ptr.PointerByReference;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API;\n\n/**\n * This message is posted by elements that have discovered new tags.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-tag\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-tag</a>\n * <p>\n */\npublic class TagMessage extends Message {\n\n    /**\n     * Creates a new Tag message.\n     *\n     * @param init internal initialization data.\n     */\n    TagMessage(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Creates a new Tag message.\n     *\n     * @param src The object originating the message.\n     * @param tagList the tag list for this message.\n     * <p>\n     * <b> Note: </b> the message takes ownership of the taglist, so do not use\n     * it again after adding it to this message.\n     */\n    public TagMessage(GstObject src, TagList tagList) {\n        this(Natives.initializer(GSTMESSAGE_API.ptr_gst_message_new_tag(src, tagList)));\n    }\n\n    /**\n     * Gets the list of tags contained in this message.\n     *\n     * @return the list of tags in this message.\n     */\n    public TagList getTagList() {\n        PointerByReference list = new PointerByReference();\n        GSTMESSAGE_API.gst_message_parse_tag(this, list);\n        return Natives.objectFor(list.getValue(), TagList.class, false, true);\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/message/WarningMessage.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.message;\n\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GErrorStruct;\nimport static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API;\n\n/**\n * This message is posted by element when a warning notice is required.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-warning\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-warning</a>\n * <p>\n */\npublic class WarningMessage extends GErrorMessage {\n\n    /**\n     * Creates a new warning message.\n     *\n     * @param init internal initialization data.\n     */\n    WarningMessage(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Retrieves the GError structure contained in this message.\n     *\n     * @return the GError contained in this message.\n     */\n    @Override\n    GErrorStruct parseMessage() {\n        GErrorStruct[] err = {null};\n        GSTMESSAGE_API.gst_message_parse_warning(this, err, null);\n        return err[0];\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/query/AllocationQuery.java",
    "content": "/*\n * Copyright (c) 2022 Neil C Smith\n * Copyright (c) 2016 Christophe Lafolet\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.query;\n\nimport org.freedesktop.gstreamer.BufferPool;\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.Structure;\nimport org.freedesktop.gstreamer.lowlevel.GType;\nimport org.freedesktop.gstreamer.lowlevel.GstQueryAPI;\n\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.glib.Natives;\n\n/**\n * An allocation query for querying allocation properties.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-allocation\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-allocation</a>\n * <p>\n *\n */\npublic class AllocationQuery extends Query {\n\n    /**\n     * This constructor is for internal use only.\n     *\n     * @param init initialization data.\n     */\n    AllocationQuery(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Create a new allocation query.\n     *\n     * @param caps the negotiated {@link Caps}\n     * @param need_pool return a pool.\n     */\n    public AllocationQuery(Caps caps, boolean need_pool) {\n        this(Natives.initializer(GstQueryAPI.GSTQUERY_API.ptr_gst_query_new_allocation(caps, need_pool)));\n    }\n\n    /**\n     * Whether a {@link BufferPool} is needed.\n     *\n     * @return true if BufferPool needed\n     */\n    public boolean isPoolNeeded() {\n        boolean[] need_pool = {false};\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_allocation(this, null, need_pool);\n        return need_pool[0];\n    }\n\n    /**\n     * Get the requested {@link Caps}\n     *\n     * @return requested Caps\n     */\n    public Caps getCaps() {\n        Pointer[] ptr = new Pointer[1];\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_allocation(this, ptr, null);\n//    \treturn new Caps(new Initializer(ptr[0], false, true));\n        return Natives.objectFor(ptr[0], Caps.class, false, true);\n    }\n\n    // @TODO how best not to expose GType?\n    void addAllocationMeta(GType api, Structure params) {\n        GstQueryAPI.GSTQUERY_API.gst_query_add_allocation_meta(this, api, params);\n    }\n\n    /**\n     * Set the pool parameters of the query.\n     *\n     * @param pool the {@link BufferPool}\n     * @param size the buffer size\n     * @param min_buffers the min buffers\n     * @param max_buffers the max buffers\n     */\n    public void addAllocationPool(BufferPool pool, int size, int min_buffers, int max_buffers) {\n        GstQueryAPI.GSTQUERY_API.gst_query_add_allocation_pool(this, pool, size, min_buffers, max_buffers);\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/query/ConvertQuery.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wim.taymans@chello.be>\n *                    2005 Wim Taymans <wim@fluendo.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.query;\n\nimport org.freedesktop.gstreamer.Format;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GstQueryAPI;\n\n/**\n * A convert query used to ask for a conversion between one format and another.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-convert\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-convert</a>\n * <p>\n */\npublic class ConvertQuery extends Query {\n\n    ConvertQuery(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Construct a new convert query object.\n     *\n     * @param srcFormat the source {@link Format} for the new query\n     * @param value the value to convert\n     * @param destFormat the target {@link Format}\n     */\n    public ConvertQuery(Format srcFormat, long value, Format destFormat) {\n        this(Natives.initializer(GstQueryAPI.GSTQUERY_API.ptr_gst_query_new_convert(srcFormat, value, destFormat)));\n    }\n\n    /**\n     * Answer a convert query by setting the requested values.\n     *\n     * @param srcFormat the source {@link Format}\n     * @param srcValue the source value\n     * @param dstFormat the destination {@link Format}\n     * @param dstValue the destination value\n     */\n    public void setConvert(Format srcFormat, long srcValue, Format dstFormat, long dstValue) {\n        GstQueryAPI.GSTQUERY_API.gst_query_set_convert(this, srcFormat, srcValue, dstFormat, dstValue);\n    }\n\n    /**\n     * Get the source {@link Format} of this query.\n     *\n     * @return source Format\n     */\n    public Format getSourceFormat() {\n        Format[] fmt = new Format[1];\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_convert(this, fmt, null, null, null);\n        return fmt[0];\n    }\n\n    /**\n     * Get the destination {@link Format} of this query.\n     *\n     * @return destination Format\n     */\n    public Format getDestinationFormat() {\n        Format[] fmt = new Format[1];\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_convert(this, null, null, fmt, null);\n        return fmt[0];\n    }\n\n    /**\n     * Get the source value of this query.\n     *\n     * @return source value\n     */\n    public long getSourceValue() {\n        long[] value = new long[1];\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_convert(this, null, value, null, null);\n        return value[0];\n    }\n\n    /**\n     * Get the destination value of this query.\n     *\n     * @return destination value\n     */\n    public long getDestinationValue() {\n        long[] value = new long[1];\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_convert(this, null, null, null, value);\n        return value[0];\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/query/DurationQuery.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wim.taymans@chello.be>\n *                    2005 Wim Taymans <wim@fluendo.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.query;\n\nimport org.freedesktop.gstreamer.Format;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GstQueryAPI;\n\n/**\n * A duration query used to get the total length of a stream.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-duration\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-duration</a>\n * <p>\n * @see Format\n */\npublic class DurationQuery extends Query {\n\n    DurationQuery(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Constructs a new stream duration query object to query in the given\n     * format. A duration query will give the total length of the stream.\n     *\n     * @param format the {@link Format} for this duration query.\n     */\n    public DurationQuery(Format format) {\n        super(Natives.initializer(GstQueryAPI.GSTQUERY_API.ptr_gst_query_new_duration(format)));\n    }\n\n    /**\n     * Answers a duration query by setting the requested value in the given\n     * format.\n     *\n     * @param format the {@link Format} for the duration\n     * @param duration the duration of the stream\n     */\n    public void setDuration(Format format, long duration) {\n        GstQueryAPI.GSTQUERY_API.gst_query_set_duration(this, format, duration);\n    }\n\n    /**\n     * Gets the format of this duration query.\n     *\n     * @return The {@link Format} of the duration value.\n     */\n    public Format getFormat() {\n        Format[] fmt = new Format[1];\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_duration(this, fmt, null);\n        return fmt[0];\n    }\n\n    /**\n     * Gets the duration answer for this query, in the format available from \n     * {@link #getFormat() }\n     *\n     * @return The total duration.\n     */\n    public long getDuration() {\n        long[] duration = new long[1];\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_duration(this, null, duration);\n        return duration[0];\n    }\n\n    /**\n     * Gets the duration as a user-readable string.\n     *\n     * @return A string representing the duration.\n     */\n    @Override\n    public String toString() {\n        return String.format(\"duration: [format=%s, duration=%d]\", getFormat(), getDuration());\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/query/FormatsQuery.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wim.taymans@chello.be>\n *                    2005 Wim Taymans <wim@fluendo.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.query;\n\nimport java.util.AbstractList;\nimport java.util.List;\n\nimport org.freedesktop.gstreamer.Format;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GstQueryAPI;\n\n/**\n * Used for querying formats of the stream.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-formats\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-formats</a>\n * <p>\n * @see Format\n */\npublic class FormatsQuery extends Query {\n\n    /**\n     * Constructs a new query object for querying formats of the stream.\n     */\n    public FormatsQuery() {\n        this(Natives.initializer(GstQueryAPI.GSTQUERY_API.ptr_gst_query_new_formats()));\n    }\n\n    FormatsQuery(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Sets the formats query result fields.\n     *\n     * @param formats the formats to set.\n     */\n    public void setFormats(Format... formats) {\n        GstQueryAPI.GSTQUERY_API.gst_query_set_formats(this, formats.length, formats);\n    }\n\n    /**\n     * Gets the number of formats in this query.\n     *\n     * @return the number of formats in this query.\n     */\n    public int getCount() {\n        int[] count = {0};\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_n_formats(this, count);\n        return count[0];\n    }\n\n    /**\n     * Gets a format at {@code index}.\n     *\n     * @param index the index of the format to retrieve.\n     * @return the format.\n     */\n    public Format getFormat(int index) {\n        Format[] fmt = new Format[1];\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_nth_format(this, index, fmt);\n        return fmt[0];\n    }\n\n    /**\n     * Gets all formats in this query.\n     *\n     * @return a {@link List} of {@link Format}.\n     */\n    public List<Format> getFormats() {\n        final int count = getCount();\n        return new AbstractList<Format>() {\n            @Override\n            public Format get(int index) {\n                return getFormat(index);\n            }\n\n            @Override\n            public int size() {\n                return count;\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/query/LatencyQuery.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wim.taymans@chello.be>\n *                    2005 Wim Taymans <wim@fluendo.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.query;\n\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GstQueryAPI;\n\n/**\n * Used for querying the latency of the stream.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-latency\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-latency</a>\n * <p>\n */\npublic class LatencyQuery extends Query {\n\n    LatencyQuery(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Constructs a new query stream position query object. A position query is\n     * used to query the current position of playback in the streams, in some\n     * format.\n     */\n    public LatencyQuery() {\n        super(Natives.initializer(GstQueryAPI.GSTQUERY_API.ptr_gst_query_new_latency()));\n    }\n\n    /**\n     * Answers a latency query.\n     *\n     * @param live if there is a live element upstream\n     * @param minLatency the minimal latency of the live element\n     * @param maxLatency the maximal latency of the live element\n     */\n    public void setLatency(boolean live, long minLatency, long maxLatency) {\n        GstQueryAPI.GSTQUERY_API.gst_query_set_latency(this, live, minLatency, maxLatency);\n    }\n\n    /**\n     * Gets whether the element has a live element upstream or not.\n     *\n     * @return true if the element has a live element upstream.\n     */\n    public boolean isLive() {\n        boolean[] live = new boolean[1];\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_latency(this, live, null, null);\n        return live[0];\n    }\n\n    /**\n     * Gets the minimum latency of the live element.\n     *\n     * @return The minimum latency of the live element.\n     */\n    public long getMinimumLatency() {\n        long[] latency = new long[1];\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_latency(this, null, latency, null);\n        return latency[0];\n    }\n\n    /**\n     * Gets the maximum latency of the live element.\n     *\n     * @return The maximum latency of the live element.\n     */\n    public long getMaximumLatency() {\n        long[] latency = new long[1];\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_latency(this, null, null, latency);\n        return latency[0];\n    }\n\n    /**\n     * Gets the latency as a user-readable string.\n     *\n     * @return A string representing the latency.\n     */\n    @Override\n    public String toString() {\n        return String.format(\"latency:[live=%b, min=%s, max=%s]\",\n                isLive(), getMinimumLatency(), getMaximumLatency());\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/query/PositionQuery.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wim.taymans@chello.be>\n *                    2005 Wim Taymans <wim@fluendo.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.query;\n\nimport org.freedesktop.gstreamer.Format;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GstQueryAPI;\n\n/**\n * Used to query an element for the current position in the stream.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-position\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-position</a>\n * <p>\n */\npublic class PositionQuery extends Query {\n\n    PositionQuery(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Constructs a new query stream position query object. A position query is\n     * used to query the current position of playback in the streams, in some\n     * format.\n     *\n     * @param format the default {@link Format} for the new query\n     */\n    public PositionQuery(Format format) {\n        super(Natives.initializer(GstQueryAPI.GSTQUERY_API.ptr_gst_query_new_position(format)));\n    }\n\n    /**\n     * Answers a position query by setting the requested value in the given\n     * format.\n     *\n     * @param format the requested {@link Format}\n     * @param position the position to set in the answer\n     */\n    public void setPosition(Format format, long position) {\n        GstQueryAPI.GSTQUERY_API.gst_query_set_position(this, format, position);\n    }\n\n    /**\n     * Gets the {@link Format} of this position query.\n     *\n     * @return The format of the query.\n     */\n    public Format getFormat() {\n        Format[] fmt = new Format[1];\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_position(this, fmt, null);\n        return fmt[0];\n    }\n\n    /**\n     * Gets the position in terms of the {@link Format} of the query.\n     *\n     * @return the position.\n     */\n    public long getPosition() {\n        long[] pos = new long[1];\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_position(this, null, pos);\n        return pos[0];\n    }\n\n    /**\n     * Gets the position as a user-readable string.\n     *\n     * @return A string representation of the position.\n     */\n    @Override\n    public String toString() {\n        return String.format(\"position: [format=%s, position=%d]\", getFormat(), getPosition());\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/query/Query.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.query;\n\nimport java.util.EnumMap;\nimport java.util.Map;\nimport java.util.function.Function;\nimport java.util.stream.Stream;\nimport org.freedesktop.gstreamer.Element;\nimport org.freedesktop.gstreamer.MiniObject;\nimport org.freedesktop.gstreamer.Pad;\nimport org.freedesktop.gstreamer.Structure;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GstQueryAPI;\nimport org.freedesktop.gstreamer.lowlevel.ReferenceManager;\nimport org.freedesktop.gstreamer.lowlevel.annotations.HasSubtype;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstQueryAPI.GSTQUERY_API;\n\n/**\n * Base query type. Queries can be performed on {@link Pad} and {@link Element}.\n * Some queries might need a running pipeline to work.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html</a>\n */\n@HasSubtype\npublic class Query extends MiniObject {\n\n    public static final String GTYPE_NAME = \"GstQuery\";\n\n    private static final Map<QueryType, Function<Initializer, Query>> TYPE_MAP\n            = new EnumMap<>(QueryType.class);\n\n    static {\n        TYPE_MAP.put(QueryType.ALLOCATION, AllocationQuery::new);\n        TYPE_MAP.put(QueryType.CONVERT, ConvertQuery::new);\n        TYPE_MAP.put(QueryType.DURATION, DurationQuery::new);\n        TYPE_MAP.put(QueryType.FORMATS, FormatsQuery::new);\n        TYPE_MAP.put(QueryType.LATENCY, LatencyQuery::new);\n        TYPE_MAP.put(QueryType.POSITION, PositionQuery::new);\n        TYPE_MAP.put(QueryType.SEEKING, SeekingQuery::new);\n        TYPE_MAP.put(QueryType.SEGMENT, SegmentQuery::new);\n    }\n\n    /**\n     * Internally used constructor. Do not use.\n     *\n     * @param init internal initialization data.\n     */\n    Query(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Get the structure of this query.\n     *\n     * @return The structure of this Query.\n     */\n    public Structure getStructure() {\n        return ReferenceManager.addKeepAliveReference(GSTQUERY_API.gst_query_get_structure(this), this);\n    }\n\n    private static Query create(Initializer init) {\n        GstQueryAPI.QueryStruct struct = new GstQueryAPI.QueryStruct(init.ptr.getPointer());\n        QueryType type = (QueryType) struct.readField(\"type\");\n        return TYPE_MAP.getOrDefault(type, Query::new).apply(init);\n    }\n    \n    public static class Types implements TypeProvider {\n\n        @Override\n        public Stream<TypeRegistration<?>> types() {\n            return Stream.of(\n                    Natives.registration(Query.class, GTYPE_NAME, Query::create)\n            );\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/query/QueryType.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wim.taymans@chello.be>\n *                    2005 Wim Taymans <wim@fluendo.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.query;\n\nimport org.freedesktop.gstreamer.Gst;\nimport org.freedesktop.gstreamer.glib.NativeEnum;\n\n/**\n * Standard predefined Query types\n */\npublic enum QueryType implements NativeEnum<QueryType> {\n\n    /**\n     * invalid query type\n     */\n    UNKNOWN(0, 0),\n    /**\n     * current position in stream\n     */\n    POSITION(10, Flags.BOTH),\n    /**\n     * total duration of the stream\n     */\n    DURATION(20, Flags.BOTH),\n    /**\n     * latency of stream\n     */\n    LATENCY(30, Flags.BOTH),\n    /**\n     * current jitter of stream\n     */\n    JITTER(40, Flags.BOTH),\n    /**\n     * current rate of the stream\n     */\n    RATE(50, Flags.BOTH),\n    /**\n     * seeking capabilities\n     */\n    SEEKING(60, Flags.BOTH),\n    /**\n     * segment start/stop positions\n     */\n    SEGMENT(70, Flags.BOTH),\n    /**\n     * convert values between formats\n     */\n    CONVERT(80, Flags.BOTH),\n    /**\n     * query supported formats for convert\n     */\n    FORMATS(90, Flags.BOTH),\n    /**\n     * query available media for efficient seeking\n     */\n    BUFFERING(110, Flags.BOTH),\n    /**\n     * a custom application or element defined query\n     */\n    CUSTOM(120, Flags.BOTH),\n    /**\n     * query the URI of the source or sink\n     */\n    URI(130, Flags.BOTH),\n    /**\n     * the buffer allocation properties\n     */\n    ALLOCATION(140, Flags.DOWNSTREAM | Flags.SERIALIZED),\n    /**\n     * the scheduling properties\n     */\n    SCHEDULING(150, Flags.UPSTREAM),\n    /**\n     * the accept caps query\n     */\n    ACCEPT_CAPS(160, Flags.BOTH),\n    /**\n     * the caps query\n     */\n    CAPS(170, Flags.BOTH),\n    /**\n     * wait till all serialized data is consumed downstream\n     */\n    DRAIN(180, Flags.DOWNSTREAM | Flags.SERIALIZED),\n    /**\n     * query the pipeline-local context from downstream or upstream (since 1.2)\n     */\n    CONTEXT(190, Flags.BOTH),\n    \n    /**\n     * the bitrate query (since 1.16)\n     */\n    @Gst.Since(minor = 16)\n    BITRATE(200, Flags.DOWNSTREAM);\n\n    private static final int SHIFT = 8;\n\n    private final int value;\n\n    private QueryType(int num, int flags) {\n        this.value = (num << SHIFT) | flags;\n    }\n\n    private QueryType(int value) {\n        this.value = value;\n    }\n\n    /**\n     * Gets the integer value of the enum.\n     *\n     * @return the integer value for this enum.\n     */\n    public int intValue() {\n        return value;\n    }\n\n    private static final class Flags {\n\n        public static final int UPSTREAM = 1 << 0;\n        public static final int DOWNSTREAM = 1 << 1;\n        public static final int SERIALIZED = 1 << 2;\n        public static final int BOTH = UPSTREAM | DOWNSTREAM;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/query/SeekingQuery.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wim.taymans@chello.be>\n *                    2005 Wim Taymans <wim@fluendo.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.query;\n\nimport org.freedesktop.gstreamer.Format;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GstQueryAPI;\n\n/**\n * Used for querying the seeking properties of the stream.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-seeking\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-seeking</a>\n * <p>\n */\npublic class SeekingQuery extends Query {\n\n    SeekingQuery(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Constructs a new query object for querying seeking properties of the\n     * stream.\n     *\n     * @param format the default {@link Format} for the new query.\n     */\n    public SeekingQuery(Format format) {\n        this(Natives.initializer(GstQueryAPI.GSTQUERY_API.ptr_gst_query_new_seeking(format)));\n    }\n\n    /**\n     * Sets the seeking query result fields.\n     *\n     * @param format the format to set for the {@code start} and {@code end}\n     * values.\n     * @param seekable the seekable flag to set\n     * @param start the start of the segment.\n     * @param end the end of the segment.\n     */\n    public void setSeeking(Format format, boolean seekable, long start, long end) {\n        GstQueryAPI.GSTQUERY_API.gst_query_set_seeking(this, format, seekable, start, end);\n    }\n\n    /**\n     * Checks if the stream is seekable.\n     *\n     * @return {@code true} if the stream is seekable.\n     */\n    public boolean isSeekable() {\n        boolean[] value = {false};\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_seeking(this, null, value, null, null);\n        return value[0];\n    }\n\n    /**\n     * Gets the {@link Format} of the start and end values for the segment.\n     *\n     * @return the format of the start and end values.\n     */\n    public Format getFormat() {\n        Format[] value = {Format.UNDEFINED};\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_seeking(this, value, null, null, null);\n        return value[0];\n    }\n\n    /**\n     * Gets the start of the segment.\n     *\n     * @return the start of the segment.\n     */\n    public long getStart() {\n        long[] value = {0};\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_seeking(this, null, null, value, null);\n        return value[0];\n    }\n\n    /**\n     * Gets the end of the segment.\n     *\n     * @return the end of the segment.\n     */\n    public long getEnd() {\n        long[] value = {0};\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_seeking(this, null, null, null, value);\n        return value[0];\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/query/SegmentQuery.java",
    "content": "/* \n * Copyright (C) 2019 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>\n *                    2000 Wim Taymans <wim.taymans@chello.be>\n *                    2005 Wim Taymans <wim@fluendo.com>\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.query;\n\nimport org.freedesktop.gstreamer.Format;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GstQueryAPI;\n\n/**\n * Used to discover information about the currently configured segment for\n * playback.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-segment\"\n * >https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-segment</a>\n * <p>\n */\npublic class SegmentQuery extends Query {\n\n    SegmentQuery(Initializer init) {\n        super(init);\n    }\n\n    /**\n     * Constructs a new segment query object.\n     *\n     * @param format the {@link Format} for the new query.\n     */\n    public SegmentQuery(Format format) {\n        this(Natives.initializer(GstQueryAPI.GSTQUERY_API.ptr_gst_query_new_segment(format)));\n    }\n\n    /**\n     * Answers a segment query by setting the requested values.\n     * <p>\n     * The normal playback segment of a pipeline is 0 to duration at the default\n     * rate of 1.0. If a seek was performed on the pipeline to play a different\n     * segment, this query will return the range specified in the last seek.\n     *\n     * {@code startValue} and {@code stopValue} will respectively contain the\n     * configured playback range start and stop values expressed in format. The\n     * values are always between 0 and the duration of the media and\n     * {@code startValue <= stopValue}. {@code rate} will contain the playback\n     * rate. For negative rates, playback will actually happen from\n     * {@code stopValue} to {@code startValue}.\n     *\n     * @param rate the rate of the segment.\n     * @param format the {@link Format} of the segment values.\n     * @param startValue the start value.\n     * @param stopValue the stop value.\n     */\n    public void setSegment(double rate, Format format, long startValue, long stopValue) {\n        GstQueryAPI.GSTQUERY_API.gst_query_set_segment(this, rate, format, startValue, stopValue);\n    }\n\n    /**\n     * Gets the rate of the segment Query.\n     *\n     * @return the rate of the segment.\n     */\n    public double getRate() {\n        double[] rate = new double[1];\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_segment(this, rate, null, null, null);\n        return rate[0];\n    }\n\n    /**\n     * Gets the format of the start and stop values in the segment query.\n     *\n     * @return The format for the start and stop values.\n     */\n    public Format getFormat() {\n        Format[] fmt = new Format[1];\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_segment(this, null, fmt, null, null);\n        return fmt[0];\n    }\n\n    /**\n     * Gets the start of the playback range.\n     *\n     * @return the start of the playback range.\n     */\n    public long getStart() {\n        long[] value = new long[1];\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_segment(this, null, null, value, null);\n        return value[0];\n    }\n\n    /**\n     * Gets the end of the playback range.\n     *\n     * @return the end of the playback range.\n     */\n    public long getEnd() {\n        long[] value = new long[1];\n        GstQueryAPI.GSTQUERY_API.gst_query_parse_segment(this, null, null, null, value);\n        return value[0];\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/video/Video.java",
    "content": "/*\n * Copyright (c) 2020 Neil C Smith\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.video;\n\nimport java.util.stream.Stream;\nimport org.freedesktop.gstreamer.glib.NativeObject;\n\nimport static org.freedesktop.gstreamer.glib.Natives.registration;\n\n/**\n * Utility class for GStreamer Video library.\n */\npublic final class Video {\n\n    private Video() {\n    }\n\n    /**\n     * TypeProvider implementation for GStreamer Video library.\n     */\n    public static class Types implements NativeObject.TypeProvider {\n\n        @Override\n        public Stream<NativeObject.TypeRegistration<?>> types() {\n            return Stream.of(\n                    registration(VideoTimeCodeMeta.class, VideoTimeCodeMeta.GTYPE_NAME,\n                            VideoTimeCodeMeta::new)\n            );\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/video/VideoTimeCode.java",
    "content": "/*\n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2020 Petr Lastovka\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.video;\n\nimport org.freedesktop.gstreamer.Gst;\nimport org.freedesktop.gstreamer.glib.NativeObject;\nimport org.freedesktop.gstreamer.lowlevel.GPointer;\nimport org.freedesktop.gstreamer.lowlevel.GstVideoAPI;\nimport org.freedesktop.gstreamer.lowlevel.GstVideoAPI.GstVideoTimeCodeStruct;\n\n\n/**\n * A representation of a SMPTE time code.\n *\n * See <a href=\"https://gstreamer.freedesktop.org/documentation/video/gstvideotimecode.html\"\n * >https://gstreamer.freedesktop.org/documentation/video/gstvideotimecode.html</a>\n */\n@Gst.Since(minor = 10)\npublic class VideoTimeCode extends NativeObject {\n\n    private final GstVideoTimeCodeStruct timeCodeStruct;\n    private final VideoTimeCodeConfig timeCodeConfig;\n\n//    public VideoTimeCode(){\n//        this(Natives.initializer(GstVideoAPI.GSTVIDEO_API.gst_video_time_code_new_empty()));\n//    }\n\n    VideoTimeCode(GstVideoTimeCodeStruct struct) {\n        this(struct, new Handle(new GPointer(struct.getPointer()), false));\n    }\n    \n    private VideoTimeCode(GstVideoTimeCodeStruct struct, Handle handle) {\n        super(handle);\n        this.timeCodeStruct = struct;\n        timeCodeConfig = new VideoTimeCodeConfig(timeCodeStruct.config);\n    }\n\n    public VideoTimeCodeConfig getConfig() {\n        return timeCodeConfig;\n    }\n\n    /**\n     * Hours field, must be less than 24.\n     *\n     * @return number of hours\n     */\n    public int getHours() {\n        return timeCodeStruct.hours;\n    }\n\n    /**\n     * Minutes field, must be less than 60.\n     *\n     * @return number of minutes\n     */\n    public int getMinutes() {\n        return timeCodeStruct.minutes;\n    }\n\n    /**\n     * Second field, must be less than 60.\n     *\n     * @return number of seconds\n     */\n    public int getSeconds() {\n        return timeCodeStruct.seconds;\n    }\n\n    /**\n     * Frames field.\n     *\n     * @return number of seconds\n     */\n    public int getFrames() {\n        return timeCodeStruct.frames;\n    }\n\n    @Override\n    public String toString() {\n        return \"GstVideoTimeCode{\" + getHours() + \":\" + getMinutes() + \":\" + getSeconds() + \":\" + getFrames() + \", timeconfig=\" + timeCodeConfig + \"}\";\n    }\n\n    @Override\n    public void disown() {\n        timeCodeConfig.disown();\n        super.disown();\n    }\n\n    private static final class Handle extends NativeObject.Handle{\n\n        /**\n         * Construct a Handle for the supplied native reference.\n         *\n         * @param ptr           native reference\n         * @param ownsReference whether the Handle owns the native reference and\n         */\n        public Handle(GPointer ptr, boolean ownsReference) {\n            super(ptr, ownsReference);\n        }\n\n        @Override\n        protected void disposeNativeHandle(GPointer ptr) {\n            GstVideoAPI.GSTVIDEO_API.gst_video_time_code_free(ptr.getPointer());\n        }\n\n        @Override\n        protected GPointer getPointer() {\n            return super.getPointer();\n        }\n        \n        \n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/video/VideoTimeCodeConfig.java",
    "content": "/*\n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2020 Petr Lastovka\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.video;\n\nimport java.util.EnumSet;\nimport org.freedesktop.gstreamer.Gst;\nimport org.freedesktop.gstreamer.glib.NativeFlags;\nimport org.freedesktop.gstreamer.glib.NativeObject;\nimport org.freedesktop.gstreamer.lowlevel.GPointer;\nimport org.freedesktop.gstreamer.lowlevel.GstVideoAPI.GstVideoTimeCodeConfigStruct;\n\n/**\n * The configuration of the time code.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/documentation/video/gstvideotimecode.html#GstVideoTimeCodeConfig\">\n * https://gstreamer.freedesktop.org/documentation/video/gstvideotimecode.html#GstVideoTimeCodeConfig</a>\n */\n@Gst.Since(minor = 10)\npublic class VideoTimeCodeConfig extends NativeObject {\n\n    private final GstVideoTimeCodeConfigStruct timeCodeConfig;\n\n    VideoTimeCodeConfig(GstVideoTimeCodeConfigStruct struct) {\n        this(struct, new Handle(new GPointer(struct.getPointer()), false));\n    }\n\n    private VideoTimeCodeConfig(GstVideoTimeCodeConfigStruct struct, Handle handle) {\n        super(handle);\n        timeCodeConfig = struct;\n    }\n\n    /**\n     * The corresponding {@link VideoTimeCodeFlags}.\n     *\n     * @return return flags for current timecode\n     */\n    public EnumSet<VideoTimeCodeFlags> getFlags() {\n        return NativeFlags.fromInt(VideoTimeCodeFlags.class, timeCodeConfig.flags);\n    }\n\n    /**\n     * Numerator of the frame rate.\n     *\n     * @return numerator\n     */\n    public int getNumerator() {\n        return timeCodeConfig.fps_n;\n    }\n\n    /**\n     * Denominator of the frame rate.\n     *\n     * @return denominator\n     */\n    public int getDenominator() {\n        return timeCodeConfig.fps_d;\n    }\n\n    @Override\n    public String toString() {\n        final StringBuffer sb = new StringBuffer(\"GstVideoTimeCodeConfig{\");\n        sb.append(\"flags=\").append(getFlags())\n                .append(\", numerator=\").append(getNumerator())\n                .append(\", denominator=\").append(getDenominator())\n                .append('}');\n        return sb.toString();\n    }\n\n    private static final class Handle extends NativeObject.Handle {\n\n        /**\n         * Construct a Handle for the supplied native reference.\n         *\n         * @param ptr           native reference\n         * @param ownsReference whether the Handle owns the native reference and\n         */\n        public Handle(GPointer ptr, boolean ownsReference) {\n            super(ptr, ownsReference);\n        }\n\n        @Override\n        protected void disposeNativeHandle(GPointer ptr) {\n            // usually video timecode config will be released together with video timecode\n            //            GlibAPI.GLIB_API.g_free(ptr.getPointer());\n        }\n\n        @Override\n        protected GPointer getPointer() {\n            return super.getPointer();\n        }\n        \n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/video/VideoTimeCodeFlags.java",
    "content": "/*\n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2020 Petr Lastovka\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.video;\n\nimport org.freedesktop.gstreamer.glib.NativeFlags;\n\n/**\n * Flags related to the time code information. For drop frame, only 30000/1001\n * and 60000/1001 frame rates are supported.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/documentation/video/gstvideotimecode.html#GstVideoTimeCodeFlags\"\n * >https://gstreamer.freedesktop.org/documentation/video/gstvideotimecode.html#GstVideoTimeCodeFlags</a>\n */\npublic enum VideoTimeCodeFlags implements NativeFlags<VideoTimeCodeFlags> {\n//    /**\n//     * No flags\n//     */\n//    GST_VIDEO_TIME_CODE_FLAGS_NONE(0), // No flags\n    /**\n     * Whether we have drop frame rate\n     */\n    GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME(1),\n    /**\n     * Whether we have interlaced video\n     */\n    GST_VIDEO_TIME_CODE_FLAGS_INTERLACED(2);\n\n\n    private final int value;\n\n    VideoTimeCodeFlags(int value) {\n        this.value = value;\n    }\n\n    @Override\n    public int intValue() {\n        return value;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/video/VideoTimeCodeMeta.java",
    "content": "/*\n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2020 Petr Lastovka\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.video;\n\nimport org.freedesktop.gstreamer.Gst;\nimport org.freedesktop.gstreamer.Meta;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstVideoAPI.GstVideoTimeCodeMetaStruct;\n\n /**\n * Extra buffer metadata describing the GstVideoTimeCode of the frame.\n * <p>\n * See upstream documentation at\n * <a href=\"https://gstreamer.freedesktop.org/documentation/video/gstvideometa.html#GstVideoTimeCodeMeta\"\n * >https://gstreamer.freedesktop.org/documentation/video/gstvideometa.html#GstVideoTimeCodeMeta</a>\n */\n@Gst.Since(minor = 10)\npublic class VideoTimeCodeMeta extends Meta {\n    \n    /**\n     * Meta.API for VideoTimeCodeMeta.\n     */\n    public static final API<VideoTimeCodeMeta> API =\n            new API(VideoTimeCodeMeta.class, \"GstVideoTimeCodeMetaAPI\");\n\n    /**\n     * Underlying GType name.\n     */\n    public static final String GTYPE_NAME = \"GstVideoTimeCodeMeta\";\n    \n    private final VideoTimeCode timeCode;\n\n    VideoTimeCodeMeta(Initializer init) {\n        super(init);\n        GstVideoTimeCodeMetaStruct metaStruct =\n                new GstVideoTimeCodeMetaStruct(init.ptr.getPointer());\n        timeCode = new VideoTimeCode(metaStruct.tc);\n    }\n\n    /**\n     * Retrieve the time code attached to frame.\n     *\n     * @return time code\n     */\n    public VideoTimeCode getTimeCode() {\n        return timeCode;\n    }\n\n    @Override\n    public void disown() {\n        timeCode.disown();\n        super.disown();\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/webrtc/WebRTC.java",
    "content": "/* \n * Copyright (c) 2019 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.webrtc;\n\nimport java.util.stream.Stream;\nimport org.freedesktop.gstreamer.glib.NativeObject;\nimport static org.freedesktop.gstreamer.glib.Natives.registration;\n\n/**\n *\n * @author Neil C Smith - https://www.neilcsmith.net\n */\npublic class WebRTC {\n\n    private WebRTC() {\n    }\n\n    public static class Types implements NativeObject.TypeProvider {\n\n        @Override\n        public Stream<NativeObject.TypeRegistration<?>> types() {\n            return Stream.of(\n                    registration(WebRTCSessionDescription.class,\n                            WebRTCSessionDescription.GTYPE_NAME,\n                            WebRTCSessionDescription::new),\n                    registration(WebRTCBin.class,\n                            WebRTCBin.GTYPE_NAME,\n                            WebRTCBin::new));\n\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/webrtc/WebRTCBin.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2018 Antonio Morales\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.webrtc;\n\nimport org.freedesktop.gstreamer.Bin;\nimport org.freedesktop.gstreamer.Element;\nimport org.freedesktop.gstreamer.Gst;\nimport org.freedesktop.gstreamer.Promise;\nimport org.freedesktop.gstreamer.Structure;\n\nimport org.freedesktop.gstreamer.glib.NativeEnum;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback;\n\n/**\n * WebRTCBin is an abstraction over gstreamers webrtcbin element It is\n * structured to mimic the RTCPeerConnection API that is available in web\n * browsers\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection\n *\n * @see\n * https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/blob/master/ext/webrtc/gstwebrtcbin.c\n * available since Gstreamer 1.14\n */\n@Gst.Since(minor = 14)\npublic class WebRTCBin extends Bin {\n\n    public static final String GST_NAME = \"webrtcbin\";\n    public static final String GTYPE_NAME = \"GstWebRTCBin\";\n\n    WebRTCBin(Initializer init) {\n        super(init);\n    }\n\n    public WebRTCBin(String name) {\n        super(makeRawElement(GST_NAME, name));\n    }\n\n    /**\n     * Signal emitted when this {@link WebRTCBin} is ready to do negotiation to\n     * setup a WebRTC connection Good starting point to have the WebRTCBin send\n     * an offer to potential clients\n     */\n    public static interface ON_NEGOTIATION_NEEDED {\n\n        /**\n         * @param elem the original webrtc bin that had the callback attached to\n         */\n        public void onNegotiationNeeded(Element elem);\n    }\n\n    /*\n     * Signal emmited when this {@link WebRTCBin} gets a new ice candidate\n     */\n    public static interface ON_ICE_CANDIDATE {\n\n        /**\n         * @param sdpMLineIndex the zero-based index of the m-line attribute\n         * within the SDP to which the candidate should be associated to\n         * @param candidate the ICE candidate\n         */\n        public void onIceCandidate(int sdpMLineIndex, String candidate);\n    }\n\n    /**\n     * Signal emitted when this {@link WebRTCBin} creates an offer\n     */\n    public static interface CREATE_OFFER {\n\n        /**\n         * @param a @WebRTCSessionDescription of the offer\n         */\n        public void onOfferCreated(WebRTCSessionDescription offer);\n    }\n\n    /**\n     * Signal emitted when this {@link WebRTCBin} creates an answer\n     */\n    public static interface CREATE_ANSWER {\n\n        /**\n         * @param a @WebRTCSessionDescription of the answer\n         */\n        public void onAnswerCreated(WebRTCSessionDescription answer);\n    }\n\n    /**\n     * Adds a listener for the <code>on-negotiation-needed</code> signal.\n     *\n     * @param listener\n     */\n    public void connect(final ON_NEGOTIATION_NEEDED listener) {\n        connect(ON_NEGOTIATION_NEEDED.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(Element elem) {\n                listener.onNegotiationNeeded(elem);\n            }\n        });\n    }\n\n    /**\n     * Adds a listener for the <code>on-ice-candidate</code> signal.\n     *\n     * @param listener\n     */\n    public void connect(final ON_ICE_CANDIDATE listener) {\n        connect(ON_ICE_CANDIDATE.class, listener, new GstCallback() {\n            @SuppressWarnings(\"unused\")\n            public void callback(Element elem, int sdpMLineIndex, String candidate) {\n                listener.onIceCandidate(sdpMLineIndex, candidate);\n            }\n        });\n    }\n\n    /**\n     * Create an offer that can be sent to other clients to setup a WebRTC\n     * connection.\n     * <p>\n     * In most cases {@link #setLocalDescription} should be called after an\n     * answer is created\n     *\n     * @param listener callback that is called when a offer is created\n     */\n    public void createOffer(final CREATE_OFFER listener) {\n        Promise promise = new Promise(new Promise.PROMISE_CHANGE() {\n            @SuppressWarnings(\"unused\")\n            public void onChange(Promise promise) {\n                Structure reply = promise.getReply();\n                WebRTCSessionDescription description = (WebRTCSessionDescription) reply.getValue(\"offer\");\n                listener.onOfferCreated(description);\n                promise.dispose();\n            }\n        });\n        emit(\"create-offer\", null, promise);\n    }\n\n    /**\n     * Create an answer in response to an offer received in order for the WebRTC\n     * signaling protocol to start.\n     * <p>\n     * Should be called after {@link #setRemoteDescription} is called\n     * <p>\n     * In most cases {@link #setLocalDescription} should be called after an\n     * answer is created\n     *\n     * @param listener callback that is called when an answer is created.\n     */\n    public void createAnswer(final CREATE_ANSWER listener) {\n        Promise promise = new Promise(new Promise.PROMISE_CHANGE() {\n            @SuppressWarnings(\"unused\")\n            public void onChange(Promise promise) {\n                Structure reply = promise.getReply();\n                WebRTCSessionDescription description = (WebRTCSessionDescription) reply.getValue(\"answer\");\n                listener.onAnswerCreated(description);\n                promise.dispose();\n            }\n        });\n        emit(\"create-answer\", null, promise);\n    }\n\n    /**\n     * Adds a remote ice candidate to the bin\n     *\n     * @param sdpMLineIndex the zero-based index of the m-line attribute within\n     * the SDP to which the candidate should be associated to\n     * @param candidate the ICE candidate\n     */\n    public void addIceCandidate(int sdpMLineIndex, String candidate) {\n        emit(\"add-ice-candidate\", sdpMLineIndex, candidate);\n    }\n\n    /**\n     * Sets the local description for the WebRTC connection. Should be called\n     * after {@link #createOffer} or {@link #createAnser} is called.\n     *\n     * @param description the {@link WebRTCSessionDescription} to set for the\n     * local description\n     */\n    public void setLocalDescription(WebRTCSessionDescription description) {\n        Promise promise = new Promise();\n        // the raw WebRTCBin element gets ownership of the description so it must be disown in order to prevent it from being deallocated\n        description.disown();\n        emit(\"set-local-description\", description, promise);\n        promise.interrupt();\n        promise.dispose();\n    }\n\n    /**\n     * Sets the remote description for the WebRTC connection. Shoud be called\n     * after receiving an offer or answer from other clients.\n     *\n     * @param description the {@link WebRTCSessionDescription} to set for the\n     * remote description\n     */\n    public void setRemoteDescription(WebRTCSessionDescription description) {\n        Promise promise = new Promise();\n        // the raw WebRTCBin element gets ownership of the description so it must be disown in order to prevent it from being deallocated\n        description.disown();\n        emit(\"set-remote-description\", description, promise);\n        promise.interrupt();\n        promise.dispose();\n    }\n\n    /**\n     * Sets the <code>stun-server</code> property for this {@link WebRTCBin}\n     * which is use to gather ICE data\n     *\n     * @param server STUN server url\n     */\n    public void setStunServer(String server) {\n        set(\"stun-server\", server);\n    }\n\n    /**\n     * Retrieves the STUN server that is used.\n     *\n     * @return the url for the STUN server\n     */\n    public String getStunServer() {\n        return (String) get(\"stun-server\");\n    }\n\n    /**\n     * Sets the <code>turn-server</code> property for this {@link WebRTCBin}\n     * which is used whenever a direct peer-to-peer connection can be\n     * established\n     *\n     * @param server TURN server url\n     */\n    public void setTurnServer(String server) {\n        set(\"turn-server\", server);\n    }\n\n    /**\n     * Retrieves the TURN server that is used.\n     *\n     * @return the url for the TURN server\n     */\n    public String getTurnServer() {\n        return (String) get(\"turn-server\");\n    }\n\n    /**\n     * Retrieve the connection state this {@link WebRTCBin} is currently in\n     *\n     * @return a {@link WebRTCPeerConnectionState} describing the connection\n     * state\n     */\n    public WebRTCPeerConnectionState getConnectionState() {\n        return NativeEnum.fromInt(WebRTCPeerConnectionState.class, (Integer) get(\"connection-state\"));\n    }\n\n    /**\n     * Retrieve ICE gathering state this {@link WebRTCBin} is currently in\n     *\n     * @return a {@link WebRTCICEGatheringState} describing gathering state\n     */\n    public WebRTCICEGatheringState getICEGatheringState() {\n        return NativeEnum.fromInt(WebRTCICEGatheringState.class, (Integer) get(\"ice-gathering-state\"));\n    }\n\n    /**\n     * Retrieve the local description for this {@link WebRTCBin}\n     *\n     * @return the local {@link WebRTCSessionDescription}\n     */\n    public WebRTCSessionDescription getLocalDescription() {\n        WebRTCSessionDescription description = (WebRTCSessionDescription) get(\"local-description\");\n        description.disown();\n        return description;\n    }\n\n    /**\n     * Retrieve the remote description for this {@link WebRTCBin}\n     *\n     * @return the remote {@link WebRTCSessionDescription}\n     */\n    public WebRTCSessionDescription getRemoteDescription() {\n        WebRTCSessionDescription description = (WebRTCSessionDescription) get(\"remote-description\");\n        description.disown();\n        return description;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/webrtc/WebRTCICEGatheringState.java",
    "content": "package org.freedesktop.gstreamer.webrtc;\n\nimport org.freedesktop.gstreamer.Gst;\nimport org.freedesktop.gstreamer.glib.NativeEnum;\n\n/**\n * The ICE gathering state of WebRTC peer\n * Available since GStreamer 1.14\n */\n@Gst.Since(minor = 14)\npublic enum  WebRTCICEGatheringState implements NativeEnum<WebRTCICEGatheringState> {\n    /** New gathering */\n    NEW(0),\n    /** Gathering in progress */\n    GATHERING(1),\n    /** Gathering completed */\n    COMPLETE(2);\n\n    private final int value;\n\n    private WebRTCICEGatheringState(int value) {\n        this.value = value;\n    }\n\n    @Override\n    public int intValue() {\n        return this.value;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/webrtc/WebRTCPeerConnectionState.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2018 Antonio Morales\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.webrtc;\n\nimport org.freedesktop.gstreamer.Gst;\nimport org.freedesktop.gstreamer.glib.NativeEnum;\n\n/**\n * The state of a WebRTC peer connection\n * Available since GStreamer 1.14\n */\n@Gst.Since(minor = 14)\npublic enum WebRTCPeerConnectionState implements NativeEnum<WebRTCPeerConnectionState> {\n    /** New WebRTC connection */\n    NEW(0),\n    /** A WebRTC connection is being made */\n    CONNECTING(1),\n    /** A WebRTC connection has been made */\n    CONNECTED(2),\n    /** A WebRTC connection has been disconnected */\n    DISCONNECTED(3),\n    /** Attempt to make a WebRTC connection failed */\n    FAILED(4),\n    /** A WebRTC connection has been closed */\n    CLOSED(5);\n\n    private final int value;\n\n    private WebRTCPeerConnectionState(int value) {\n        this.value = value;\n    }\n    \n    @Override\n    public int intValue() {\n        return value;\n    }\n    \n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/webrtc/WebRTCSDPType.java",
    "content": "/* \n * Copyright (c) 2018 Antonio Morales\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.webrtc;\n\nimport org.freedesktop.gstreamer.Gst;\nimport org.freedesktop.gstreamer.glib.NativeEnum;\n\n/**\n * The type of a {@link WebRTCSessionDescription}\n * <p>\n * @see https://w3c.github.io/webrtc-pc/#rtcsdptype\n * Available since GStreamer 1.12\n */\n@Gst.Since(minor = 12)\npublic enum WebRTCSDPType implements NativeEnum<WebRTCSDPType> {\n    OFFER(1),\n    PRANSWER(2),\n    ANSWER(3),\n    ROLLBACK(4);\n    \n    private final int value;\n\n    private WebRTCSDPType(int value) {\n        this.value = value;\n    }\n\n    /**\n     * Gets the integer value of the enum\n     * @return the integer value for this enum.\n     */\n    @Override\n    public int intValue() {\n        return value;\n    }\n}\n"
  },
  {
    "path": "src/org/freedesktop/gstreamer/webrtc/WebRTCSessionDescription.java",
    "content": "/*\n * Copyright (c) 2019 Neil C Smith\n * Copyright (c) 2018 Vinicius Tona\n * Copyright (c) 2018 Antonio Morales\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under the terms of the GNU\n * Lesser General Public License version 3 only, as published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License version 3 along with\n * this work. If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.webrtc;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstWebRTCSessionDescriptionAPI.GSTWEBRTCSESSIONDESCRIPTION_API;\n\nimport org.freedesktop.gstreamer.lowlevel.GstWebRTCSessionDescriptionAPI;\nimport org.freedesktop.gstreamer.glib.NativeObject;\n\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.SDPMessage;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GPointer;\nimport static org.freedesktop.gstreamer.lowlevel.GstSDPMessageAPI.GSTSDPMESSAGE_API;\n\n/**\n * Wraps a GstWebRTCSessionDescription\n * <p>\n * See <a href=\"https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/blob/master/gst-libs/gst/webrtc/rtcsessiondescription.h\"\n * >https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/blob/master/gst-libs/gst/webrtc/rtcsessiondescription.h</a>\n */\npublic class WebRTCSessionDescription extends NativeObject {\n\n    public static final String GTYPE_NAME = \"GstWebRTCSessionDescription\";\n\n    private GstWebRTCSessionDescriptionAPI.WebRTCSessionDescriptionStruct sessionDescriptionStruct;\n\n    /**\n     * Internally used constructor. Do not use.\n     *\n     * @param init internal initialization data.\n     */\n    WebRTCSessionDescription(Initializer init) {\n        super(new Handle(init.ptr, init.ownsHandle));\n        sessionDescriptionStruct = \n                new GstWebRTCSessionDescriptionAPI.WebRTCSessionDescriptionStruct(init.ptr.getPointer());\n    }\n\n    /**\n     * Creates a new instance of WebRTCSessionDescription.\n     *\n     * @param type The {@link WebRTCSDPType} type of the session description\n     * @param sdpMessage The {@link SDPMessage} of the session description\n     */\n    public WebRTCSessionDescription(WebRTCSDPType type, SDPMessage sdpMessage) {\n        this(Natives.initializer(GSTWEBRTCSESSIONDESCRIPTION_API.ptr_gst_webrtc_session_description_new(type, sdpMessage)));\n    }\n\n    /**\n     * Gets the SDPMessage from the WebRTCSessionDescription.\n     *\n     * @return the {@link SDPMessage} for the WebRTCSessionDescription\n     */\n    public SDPMessage getSDPMessage() {\n        SDPMessage originalSDP = (SDPMessage) sessionDescriptionStruct.readField(\"sdp\");\n        // making a copy of the SDPMessage since the original SDPMessage in the struct belongs to WebRTCSessionDescription.\n        // Once WebRTCSessionDescription is disposed it would also dispose of SDPMessage leading to any objects with a reference\n        // to the original SDPMessage to be invalid and potentially lead to runtime errors.\n        \n        //    return originalSDP.copy(true);\n        Pointer[] ptr = new Pointer[1];\n        GSTSDPMESSAGE_API.gst_sdp_message_copy(originalSDP, ptr);\n        originalSDP.invalidate();\n        return Natives.objectFor(ptr[0], SDPMessage.class, false, true);\n    }\n\n    \n    private static final class Handle extends NativeObject.Handle {\n\n        public Handle(GPointer ptr, boolean ownsHandle) {\n            super(ptr, ownsHandle);\n        }\n\n        @Override\n        protected void disposeNativeHandle(GPointer ptr) {\n            GSTWEBRTCSESSIONDESCRIPTION_API.gst_webrtc_session_description_free(ptr.getPointer());\n        }\n        \n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/BinTest.java",
    "content": "/* \n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.GError;\nimport java.util.ArrayList;\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertNotNull;\nimport static org.junit.Assert.assertTrue;\nimport static org.junit.Assert.fail;\n\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.freedesktop.gstreamer.lowlevel.GstBinAPI;\nimport org.freedesktop.gstreamer.lowlevel.GstPipelineAPI;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\n/**\n *\n * @author wayne\n */\npublic class BinTest {    \n    public BinTest() {\n    }\n    \n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(\"BinTest\", new String[] {});\n    }\n    \n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n    \n    @Before\n    public void setUp() throws Exception {\n    }\n    \n    @After\n    public void tearDown() throws Exception {\n    }\n\n    @Test\n    public void testGetElements() {\n        Bin bin = new Bin(\"test\");\n        Element e1 = ElementFactory.make(\"fakesrc\", \"source\");\n        Element e2 = ElementFactory.make(\"fakesink\", \"sink\");\n        bin.addMany(e1, e2);\n        List<Element> elements = bin.getElements();\n        assertFalse(\"Bin returned empty list from getElements\", elements.isEmpty());\n        assertTrue(\"Element list does not contain e1\", elements.contains(e1));\n        assertTrue(\"Element list does not contain e2\", elements.contains(e2));\n    }\n    @Test\n    public void testGetSinks() throws Exception {\n        Bin bin = new Bin(\"test\");\n        Element e1 = ElementFactory.make(\"fakesrc\", \"source\");\n        Element e2 = ElementFactory.make(\"fakesink\", \"sink\");\n        bin.addMany(e1, e2);\n        List<Element> elements = bin.getSinks();\n        assertFalse(\"Bin returned empty list from getElements\", elements.isEmpty());\n        assertTrue(\"Element list does not contain sink\", elements.contains(e2));\n    }\n    \n    @Test\n    public void testGetSources() throws Exception {\n        Bin bin = new Bin(\"test\");\n        Element e1 = ElementFactory.make(\"fakesrc\", \"source\");\n        Element e2 = ElementFactory.make(\"fakesink\", \"sink\");\n        bin.addMany(e1, e2);\n        List<Element> elements = bin.getSources();\n        assertFalse(\"Bin returned empty list from getElements\", elements.isEmpty());\n        assertTrue(\"Element list does not contain source\", elements.contains(e1));\n    }\n    @Test\n    public void testGetElementByName() throws Exception {\n        Bin bin = new Bin(\"test\");\n        Element e1 = ElementFactory.make(\"fakesrc\", \"source\");\n        Element e2 = ElementFactory.make(\"fakesink\", \"sink\");\n        bin.addMany(e1, e2);\n        \n        assertEquals(\"source not returned\", e1, bin.getElementByName(\"source\"));\n        assertEquals(\"sink not returned\", e2, bin.getElementByName(\"sink\"));\n    }\n    \n    @Test\n    public void testElementAddedCallback() throws Exception {\n        Bin bin = new Bin(\"test\");\n        final Element e1 = ElementFactory.make(\"fakesrc\", \"source\");\n        final Element e2 = ElementFactory.make(\"fakesink\", \"sink\");\n        final AtomicInteger added = new AtomicInteger(0);\n        \n        bin.connect(new Bin.ELEMENT_ADDED() {\n            public void elementAdded(Bin bin, Element elem) {\n                if (elem == e1 || elem == e2) {\n                    added.incrementAndGet();\n                }\n            }\n        });\n        bin.addMany(e1, e2);\n        \n        assertEquals(\"Callback not called\", 2, added.get());\n    }\n    @Test\n    public void testElementRemovedCallback() {\n        Bin bin = new Bin(\"test\");\n        final Element e1 = ElementFactory.make(\"fakesrc\", \"source\");\n        final Element e2 = ElementFactory.make(\"fakesink\", \"sink\");\n        final AtomicInteger removed = new AtomicInteger(0);\n        \n        bin.connect(new Bin.ELEMENT_ADDED() {\n            public void elementAdded(Bin bin, Element elem) {\n                if (elem == e1 || elem == e2) {\n                    removed.incrementAndGet();\n                }\n            }\n        });\n        bin.addMany(e1, e2);\n        \n        assertEquals(\"Callback not called\", 2, removed.get());\n    }\n    @Test \n    public void addLinked()\n        throws PadLinkException\n    {\n        /* adding an element with linked pads to a bin unlinks the pads */\n        Pipeline pipeline = new Pipeline((String) null);\n        assertNotNull(\"Could not create pipeline\", pipeline);\n\n        Element src = ElementFactory.make(\"fakesrc\", null);\n        assertNotNull(\"Could not create fakesrc\", src);\n        Element sink = ElementFactory.make(\"fakesink\", null);\n        assertNotNull(\"Could not create fakesink\", sink);\n\n        Pad srcpad = src.getStaticPad(\"src\");\n        assertNotNull(\"Could not get src pad\", srcpad);\n        Pad sinkpad = sink.getStaticPad(\"sink\");\n        assertNotNull(\"Could not get sink pad\", sinkpad);\n        \n        srcpad.link(sinkpad);\n\n        /* pads are linked now */\n        assertTrue(\"srcpad not linked\", srcpad.isLinked());\n        assertTrue(\"sinkpad not linked\", sinkpad.isLinked());\n        \n        /* adding element to bin voids hierarchy so pads are unlinked */\n        pipeline.add(src);\n\n        /* check if pads really are unlinked */\n        assertFalse(\"srcpad is still linked after being added to bin\", srcpad.isLinked());\n        assertFalse(\"sinkpad is still linked after being added to bin\", sinkpad.isLinked());\n        \n        /* cannot link pads in wrong hierarchy */\n        try {\n            srcpad.link(sinkpad);\n            fail(\"Should not be able to link pads in different hierarchy\");\n        } catch (PadLinkException e) {\n            assertEquals(\"Should not be able to link pads in different hierarchy\",\n                PadLinkReturn.WRONG_HIERARCHY, e.getLinkResult());\n        }\n\n        /* adding other element to bin as well */\n        pipeline.add(sink);\n\n        /* now we can link again */\n        srcpad.link(sinkpad);\n\n        /* check if pads really are linked */\n        assertTrue(\"srcpad not linked\", srcpad.isLinked());\n        assertTrue(\"sinkpad not linked\", sinkpad.isLinked());\n        \n        // Force disposal to flush out any refcounting bugs.\n        pipeline.dispose(); src.dispose(); sink.dispose(); srcpad.dispose(); sinkpad.dispose();\n    }\n    @Test\n    public void addSelf() {\n        Bin bin = new Bin(\"\");\n        // Enable the line below once we know how to avoid gstreamer spitting out warnings\n        //assertFalse(\"Should not be able to add bin to itself\", bin.add(bin));\n        bin.dispose();\n    }\n    // This test doesn't work correctly on older gstreamer?\n    //@Test \n    public void iterateSorted() {\n        Pipeline pipeline = GstPipelineAPI.GSTPIPELINE_API.gst_pipeline_new(null);\n        assertNotNull(\"Failed to create Pipeline\", pipeline);\n        Bin bin = GstBinAPI.GSTBIN_API.gst_bin_new(null);\n        assertNotNull(\"Failed to create bin\", bin);\n\n        Element src = ElementFactory.make(\"fakesrc\", null);\n        assertNotNull(\"Failed to create fakesrc\", src);\n\n        Element tee = ElementFactory.make(\"tee\", null);\n        assertNotNull(\"Failed to create tee\", tee);\n\n        Element sink1 = ElementFactory.make(\"fakesink\", null);\n        assertNotNull(\"Failed to create fakesink\", sink1);\n\n        bin.addMany(src, tee, sink1);\n        assertTrue(\"Could not link fakesrc to tee\", src.link(tee));\n        assertTrue(\"Could not link tee to fakesink\", tee.link(sink1));\n\n        Element identity = ElementFactory.make(\"identity\", null);\n        assertNotNull(\"Failed to create identity\", identity);\n        \n\n        Element sink2 = ElementFactory.make(\"fakesink\", null);\n        assertNotNull(\"Failed to create fakesink\", sink2);\n        pipeline.addMany(bin, identity, sink2);\n//  gst_bin_add_many (GST_BIN (pipeline), bin, identity, sink2, NULL);\n        assertTrue(\"Could not link tee to identity\", tee.link(identity));\n        assertTrue(\"Could not link identity to second fakesink\", identity.link(sink2));\n        Iterator<Element> it = pipeline.getElementsSorted().iterator();\n        \n        assertEquals(\"First sorted element should be sink2\", sink2, it.next());\n        assertEquals(\"Second sorted element should be identity\", identity, it.next());\n        assertEquals(\"Third sorted element should be bin\", bin, it.next());\n        pipeline.dispose();\n    }\n    \n    @Test\n    public void testParseBin() {\n        ArrayList<GError> errors = new ArrayList<GError>();\n        Bin bin = Gst.parseBinFromDescription(\"fakesrc ! fakesink\", false, errors);\n        assertNotNull(\"Bin not created\", bin);\n        assertEquals(\"parseBinFromDescription with error!\", errors.size(), 0);\n    }   \n    @Test\n    public void testParseBinElementCount() {\n        ArrayList<GError> errors = new ArrayList<GError>();\n        Bin bin = Gst.parseBinFromDescription(\"fakesrc ! fakesink\", false, errors);\n        assertEquals(\"Number of elements in pipeline incorrect\", 2, bin.getElements().size());\n        assertEquals(\"parseBinFromDescription with error!\", errors.size(), 0);\n    }\n    @Test\n    public void testParseBinSrcElement() {\n        ArrayList<GError> errors = new ArrayList<GError>();\n    \tBin bin = Gst.parseBinFromDescription(\"fakesrc ! fakesink\", false, errors);\n        assertEquals(\"First element not a fakesrc\", \"fakesrc\", bin.getSources().get(0).getFactory().getName());\n        assertEquals(\"parseBinFromDescription with error!\", errors.size(), 0);\n    }\n    @Test\n    public void testParseBinSinkElement() {\n        ArrayList<GError> errors = new ArrayList<GError>();\n    \tBin bin = Gst.parseBinFromDescription(\"fakesrc ! fakesink\", false, errors);\n        assertEquals(\"First element not a fakesink\", \"fakesink\", bin.getSinks().get(0).getFactory().getName());\n        assertEquals(\"parseBinFromDescription with error!\", errors.size(), 0);\n    }\n    @Test\n    public void testParseBinDisabledGhostPadsForSource() {\n        ArrayList<GError> errors = new ArrayList<GError>();\n    \tBin bin = Gst.parseBinFromDescription(\"fakesrc\", false, errors);\n    \tassertEquals(\"Number of src pads incorrect\", 0, bin.getSrcPads().size());\n        assertEquals(\"parseBinFromDescription with error!\", errors.size(), 0);\n    }\n    @Test\n    public void testParseBinDisabledGhostPadsForSink() {\n        ArrayList<GError> errors = new ArrayList<GError>();\n    \tBin bin = Gst.parseBinFromDescription(\"fakesink\", false, errors);\n    \tassertEquals(\"Number of sink pads incorrect\", 0, bin.getSinkPads().size());\n        assertEquals(\"parseBinFromDescription with error!\", errors.size(), 0);\n    }\n    @Test\n    public void testParseBinEnabledGhostPadsForSource() {\n        ArrayList<GError> errors = new ArrayList<GError>();\n    \tBin bin = Gst.parseBinFromDescription(\"fakesrc\", true, errors);\n    \tassertEquals(\"Number of src pads incorrect\", 1, bin.getSrcPads().size());\n        assertEquals(\"parseBinFromDescription with error!\", errors.size(), 0);\n    }\n    @Test\n    public void testParseBinEnabledGhostPadsForSink() {\n        ArrayList<GError> errors = new ArrayList<GError>();\n    \tBin bin = Gst.parseBinFromDescription(\"fakesink\", true, errors);\n    \tassertEquals(\"Number of sink pads incorrect\", 1, bin.getSinkPads().size());\n        assertEquals(\"parseBinFromDescription with error!\", errors.size(), 0);\n    }\n    @Test\n    public void testParseBinEnabledGhostPadsForSourceWithNoUsablePads() {\n        ArrayList<GError> errors = new ArrayList<GError>();\n    \tBin bin = Gst.parseBinFromDescription(\"fakesrc ! fakesink\", true, errors);\n    \tassertEquals(\"Number of src pads incorrect\", 0, bin.getSrcPads().size());\n        assertEquals(\"parseBinFromDescription with error!\", errors.size(), 0);\n    }\n    @Test\n    public void testParseBinEnabledGhostPadsForSinkWithNoUsablePads() {\n        ArrayList<GError> errors = new ArrayList<GError>();\n    \tBin bin = Gst.parseBinFromDescription(\"fakesrc ! fakesink\", true, errors);\n    \tassertEquals(\"Number of sink pads incorrect\", 0, bin.getSinkPads().size());\n        assertEquals(\"parseBinFromDescription with error!\", errors.size(), 0);\n    }\n    @Test\n    public void testParseBinEnabledGhostPadsWithNoUsablePads() {\n        ArrayList<GError> errors = new ArrayList<GError>();\n    \tBin bin = Gst.parseBinFromDescription(\"fakesrc ! fakesink\", true, errors);\n    \tassertEquals(\"Number of pads incorrect\", 0, bin.getPads().size());\n        assertEquals(\"parseBinFromDescription with error!\", errors.size(), 0);\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/BufferFieldsTest.java",
    "content": "package org.freedesktop.gstreamer;\n\nimport org.junit.*;\nimport static org.junit.Assert.*;\n\n/**\n * <p>\n * Copyright (C) 2018 Robert Forsman, Ericsson SATV $Author thoth $ $Date 3/8/18\n * $\n */\npublic class BufferFieldsTest {\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(\"BufferFieldsTest\");\n    }\n    \n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n    \n    private Buffer buf;\n    \n    @Before\n    public void setUp() {\n        buf = new Buffer(12);\n    }\n    \n    @Test\n    public void setPTS() {\n        buf.setPresentationTimestamp(ClockTime.fromMicros(5004003));\n        long val = buf.getPresentationTimestamp();\n        assertEquals(5004003, ClockTime.toMicros(val));\n    }\n    \n    @Test\n    public void setDTS() {\n        buf.setDecodeTimestamp(ClockTime.fromMicros(9001004));\n        long val = buf.getDecodeTimestamp();\n        assertEquals(9001004, ClockTime.toMicros(val));\n    }\n    \n    @Test\n    public void setDuration() {\n        buf.setDuration(ClockTime.fromMicros(4006008));\n        long val = buf.getDuration();\n        assertEquals(4006008, ClockTime.toMicros(val));\n    }\n    \n    @Test\n    public void setOffset() {\n        buf.setOffset(2009006);\n        long val = buf.getOffset();\n        assertEquals(2009006, val);\n    }\n    \n    @Test\n    public void setOffsetEnd() {\n        buf.setOffsetEnd(7005003);\n        long val = buf.getOffsetEnd();\n        assertEquals(7005003, val);\n    }\n    \n    @Test\n    // cannot test on GStreamer 1.8\n    public void setFlags() {\n//        assertTrue(buf.setFlags(7));\n//        int val = buf.getFlags();\n//        assertEquals(7, val);\n//\n//        assertTrue(buf.setFlags(10));\n//        val = buf.getFlags();\n//        assertEquals(15, val);\n//\n//        assertTrue(buf.unsetFlags(20));\n//        val = buf.getFlags();\n//        assertEquals(11, val);\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/BufferProbeTester.java",
    "content": "/*\n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2020 John Cortell\n *\n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertNotNull;\nimport static org.junit.Assert.fail;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.TimeoutException;\nimport java.util.function.Consumer;\n\n/**\n * Utility class for unit testing API that operates on a Buffer.\n * <p>\n * Call {@link BufferTester#test(Consumer)} and pass a callback which will\n * perform the test on a Buffer it is supplied. The callback runs in a Pad data\n * probe. The buffer is produced by a simple, ephemeral pipeline that is fed by\n * a video test source.\n */\npublic class BufferProbeTester {\n\n    public static void test(Consumer<Buffer> callback) {\n        test(callback, \"videotestsrc ! videoconvert ! fakesink name=sink\");\n    }\n\n    public static void test(Consumer<Buffer> callback, String pipelineDescription) {\n        test(callback, pipelineDescription, 0);\n    }\n\n    public static void test(Consumer<Buffer> callback, String pipelineDescription, int skipFrames) {\n        assertNotNull(\"Pipeline description can not be null\", pipelineDescription);\n        assertFalse(\"Pipeline description can not be empty\", pipelineDescription.isEmpty());\n        Pipeline pipe = (Pipeline) Gst.parseLaunch(pipelineDescription);\n        assertNotNull(\"Unable to create Pipeline from pipeline description: \", pipe);\n\n        Element sink = pipe.getElementByName(\"sink\");\n        Pad pad = sink.getStaticPad(\"sink\");\n        BufferProbe probe = new BufferProbe(callback, skipFrames);\n        pad.addDataProbe(probe);\n\n        pipe.play();\n\n        // Wait for the sample to arrive and for the client supplied test function to\n        // complete\n        try {\n            probe.await(5000);\n        } catch (Exception ex) {\n            fail(\"Unexpected exception waiting for buffer\\n\" + ex);\n        } finally {\n            pipe.stop();\n        }\n\n        // If the test threw an exception on the sample listener thread, throw it here\n        // (on the main thread)\n        if (probe.exception != null) {\n            throw new AssertionError(probe.exception);\n        }\n    }\n\n    private static class BufferProbe implements Pad.DATA_PROBE {\n\n        private final int skipFrames;\n        private final CountDownLatch latch;\n        private final Consumer<Buffer> callback;\n\n        private Throwable exception;\n        private int counter = 0;\n\n        BufferProbe(Consumer<Buffer> callback) {\n            this(callback, 0);\n        }\n\n        BufferProbe(Consumer<Buffer> callback, int skip) {\n            this.callback = callback;\n            skipFrames = skip;\n            latch = new CountDownLatch(1);\n        }\n\n        @Override\n        public PadProbeReturn dataReceived(Pad pad, Buffer buffer) {\n            if (latch.getCount() > 0) {\n                if (counter < skipFrames) {\n                    counter++;\n                    return PadProbeReturn.OK;\n                }\n                try {\n                    // Run the client's test logic on the buffer (only once)\n                    try {\n                        callback.accept(buffer);\n                    } catch (Throwable exc) {\n                        exception = exc;\n                    }\n                } finally {\n                    latch.countDown();\n                }\n            }\n            return PadProbeReturn.OK;\n        }\n\n        void await(long millis) throws InterruptedException, TimeoutException {\n            if (!latch.await(millis, TimeUnit.MILLISECONDS)) {\n                throw new TimeoutException();\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/BusTest.java",
    "content": "/* \n * Copyright (c) 2025 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.concurrent.atomic.AtomicInteger;\nimport java.util.concurrent.atomic.AtomicLong;\nimport java.util.concurrent.atomic.AtomicReference;\nimport org.freedesktop.gstreamer.lowlevel.GlibAPI;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI.GErrorStruct;\nimport org.freedesktop.gstreamer.message.EOSMessage;\nimport org.freedesktop.gstreamer.message.Message;\nimport org.freedesktop.gstreamer.message.MessageType;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstElementAPI.GSTELEMENT_API;\nimport static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API;\nimport static org.junit.Assert.*;\n\npublic class BusTest {\n\n    public BusTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(\"BusTest\");\n    }\n\n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n\n    @Before\n    public void setUp() throws Exception {\n    }\n\n    @After\n    public void tearDown() throws Exception {\n    }\n\n    @Test\n    public void endOfStream() {\n        final TestPipe pipe = new TestPipe(\"endOfStream\");\n\n        final AtomicBoolean signalFired = new AtomicBoolean(false);\n        final AtomicReference<GstObject> signalSource = new AtomicReference<>();\n\n        Bus.EOS eosSignal = (GstObject source) -> {\n            signalFired.set(true);\n            signalSource.set(source);\n            pipe.quit();\n        };\n        pipe.play();\n        pipe.getBus().connect(eosSignal);\n        //\n        // For the pipeline to post an EOS message, all sink elements must post it\n        //\n        for (Element elem : pipe.pipe.getSinks()) {\n            GSTELEMENT_API.gst_element_post_message(elem,\n                    GSTMESSAGE_API.gst_message_new_eos(elem));\n        }\n        pipe.run();\n        pipe.getBus().disconnect(eosSignal);\n\n        assertTrue(\"EOS signal not received\", signalFired.get());\n        pipe.dispose();\n    }\n\n    @Test\n    public void stateChanged() {\n        final TestPipe pipe = new TestPipe(\"stateChanged\");\n        final AtomicBoolean signalFired = new AtomicBoolean(false);\n\n        Bus.STATE_CHANGED stateChanged = (GstObject source, State old, State current, State pending) -> {\n            if (pending == State.PLAYING || current == State.PLAYING) {\n                signalFired.set(true);\n                pipe.quit();\n            }\n        };\n        pipe.getBus().connect(stateChanged);\n        pipe.play().run();\n        pipe.getBus().disconnect(stateChanged);\n        assertTrue(\"STATE_CHANGED signal not received\", signalFired.get());\n        pipe.dispose();\n    }\n    \n    @Test\n    public void asyncDone() {\n        final TestPipe pipe = new TestPipe(\"asyncDone\");\n        final AtomicBoolean signalFired = new AtomicBoolean(false);\n\n        Bus.ASYNC_DONE asyncDone = (GstObject source) -> {\n            signalFired.set(true);\n            pipe.quit();\n        };\n        pipe.getBus().connect(asyncDone);\n        pipe.play().run();\n        pipe.getBus().disconnect(asyncDone);\n        assertTrue(\"ASYNC_DONE message not received\", signalFired.get());\n        pipe.dispose();\n    }\n\n    @Test\n    public void errorMessage() {\n        final TestPipe pipe = new TestPipe(\"errorMessage\");\n\n        final AtomicBoolean signalFired = new AtomicBoolean(false);\n        final AtomicReference<GstObject> signalSource = new AtomicReference<>();\n\n        Bus.ERROR errorSignal = (GstObject source, int code, String message) -> {\n            signalFired.set(true);\n            signalSource.set(source);\n            pipe.quit();\n        };\n        pipe.getBus().connect(errorSignal);\n\n        GErrorStruct msg = GlibAPI.GLIB_API.g_error_new(1, 1, \"MSG\");\n        GSTELEMENT_API.gst_element_post_message(pipe.src,\n                GSTMESSAGE_API.gst_message_new_error(pipe.src, msg, \"testing error messages\"));\n        pipe.play().run();\n        pipe.getBus().disconnect(errorSignal);\n        pipe.dispose();\n        assertTrue(\"ERROR signal not received\", signalFired.get());\n        assertEquals(\"Incorrect source object on signal\", pipe.src, signalSource.get());\n        GlibAPI.GLIB_API.g_error_free(msg.getPointer());\n    }\n\n    @Test\n    public void warningMessage() {\n        final TestPipe pipe = new TestPipe(\"warningMessage\");\n\n        final AtomicBoolean signalFired = new AtomicBoolean(false);\n        final AtomicReference<GstObject> signalSource = new AtomicReference<>();\n\n        Bus.WARNING signal = (GstObject source, int code, String message) -> {\n            signalFired.set(true);\n            signalSource.set(source);\n            pipe.quit();\n        };\n        pipe.getBus().connect(signal);\n\n        GErrorStruct msg = GlibAPI.GLIB_API.g_error_new(1, 1, \"MSG\");\n        pipe.play();\n        GSTELEMENT_API.gst_element_post_message(pipe.src,\n                GSTMESSAGE_API.gst_message_new_warning(pipe.src, msg, \"testing warning messages\"));\n        pipe.run();\n        pipe.getBus().disconnect(signal);\n        pipe.dispose();\n        assertTrue(\"WARNING signal not received\", signalFired.get());\n        assertEquals(\"Incorrect source object on signal\", pipe.src, signalSource.get());\n        GlibAPI.GLIB_API.g_error_free(msg.getPointer());\n    }\n\n    @Test\n    public void infoMessage() {\n        final TestPipe pipe = new TestPipe(\"infoMessage\");\n\n        final AtomicBoolean signalFired = new AtomicBoolean(false);\n        final AtomicReference<GstObject> signalSource = new AtomicReference<>();\n\n        Bus.INFO signal = (GstObject source, int code, String message) -> {\n            signalFired.set(true);\n            signalSource.set(source);\n            pipe.quit();\n        };\n        pipe.getBus().connect(signal);\n\n        GErrorStruct msg = GlibAPI.GLIB_API.g_error_new(1, 1, \"MSG\");\n        pipe.play();\n        GSTELEMENT_API.gst_element_post_message(pipe.src,\n                GSTMESSAGE_API.gst_message_new_info(pipe.src, msg, \"testing info messages\"));\n        pipe.run();\n        pipe.getBus().disconnect(signal);\n        pipe.dispose();\n        assertTrue(\"INFO signal not received\", signalFired.get());\n        assertEquals(\"Incorrect source object on signal\", pipe.src, signalSource.get());\n        GlibAPI.GLIB_API.g_error_free(msg.getPointer());\n    }\n\n    @Test\n    public void bufferingData() {\n        final TestPipe pipe = new TestPipe(\"bufferingData\");\n\n        final AtomicBoolean signalFired = new AtomicBoolean(false);\n        final AtomicInteger signalValue = new AtomicInteger(-1);\n        final AtomicReference<GstObject> signalSource = new AtomicReference<>();\n        final int PERCENT = 95;\n\n        Bus.BUFFERING signal = (GstObject source, int percent) -> {\n            signalFired.set(true);\n            signalValue.set(percent);\n            signalSource.set(source);\n            pipe.quit();\n        };\n        pipe.getBus().connect(signal);\n        GSTELEMENT_API.gst_element_post_message(pipe.src,\n                GSTMESSAGE_API.gst_message_new_buffering(pipe.src, PERCENT));\n        pipe.play().run();\n        pipe.getBus().disconnect(signal);\n        pipe.dispose();\n        assertTrue(\"BUFFERING signal not received\", signalFired.get());\n        assertEquals(\"Wrong percent value received for signal\", PERCENT, signalValue.get());\n        assertEquals(\"Incorrect source object on signal\", pipe.src, signalSource.get());\n    }\n\n    @Test\n    public void tagsFound() {\n        final TestPipe pipe = new TestPipe(\"tagsFound\");\n\n        final AtomicBoolean signalFired = new AtomicBoolean(false);\n        final AtomicReference<GstObject> signalSource = new AtomicReference<>();\n        Bus.TAG signal = (GstObject source, TagList tagList) -> {\n            signalFired.set(true);\n            signalSource.set(source);\n            pipe.quit();\n        };\n        pipe.getBus().connect(signal);\n\n        TagList tagList = new TagList();\n        GSTELEMENT_API.gst_element_post_message(pipe.src,\n                GSTMESSAGE_API.gst_message_new_tag(pipe.src, tagList));\n        pipe.play().run();\n        pipe.getBus().disconnect(signal);\n        pipe.dispose();\n        assertTrue(\"TAG signal not received\", signalFired.get());\n        assertEquals(\"Incorrect source object on signal\", pipe.src, signalSource.get());\n    }\n\n    @Test\n    public void durationChanged() {\n        final TestPipe pipe = new TestPipe(\"testDurationChanged\");\n        final AtomicBoolean signalFired = new AtomicBoolean(false);\n        final AtomicReference<GstObject> signalSource = new AtomicReference<>(null);\n        Bus.DURATION_CHANGED signal = (GstObject source) -> {\n            signalFired.set(true);\n            signalSource.set(source);\n            pipe.quit();\n        };\n        pipe.getBus().connect(signal);\n        GSTELEMENT_API.gst_element_post_message(pipe.src,\n                GSTMESSAGE_API.gst_message_new_duration_changed(pipe.src));\n        pipe.play().run();\n        pipe.getBus().disconnect(signal);\n        pipe.dispose();\n        assertTrue(\"DURATION signal not received\", signalFired.get());\n        assertEquals(\"Incorrect source object on signal\", pipe.src, signalSource.get());\n    }\n    \n    @Test\n    public void segmentDone() {\n        final TestPipe pipe = new TestPipe(\"segmentDone\");\n        final AtomicBoolean signalFired = new AtomicBoolean(false);\n        final AtomicReference<Format> formatReceived = new AtomicReference<>(null);\n        final AtomicLong positionReceived = new AtomicLong(0);\n\n        Bus.SEGMENT_DONE segmentDone = (source, format, position) -> {\n            signalFired.set(true);\n            formatReceived.set(format);\n            positionReceived.set(position);\n        };\n\n        pipe.getBus().connect(segmentDone);\n        \n        final long POSITION = 0xdeadbeef;\n        GSTELEMENT_API.gst_element_post_message(pipe.src,\n                GSTMESSAGE_API.gst_message_new_segment_done(pipe.src, Format.TIME, POSITION));\n        pipe.run();\n        \n        assertTrue(\"No segment done message received\", signalFired.get());\n        assertEquals(\"Wrong format\", Format.TIME, formatReceived.get());\n        assertEquals(\"Wrong position\", POSITION, positionReceived.get());\n        pipe.dispose();\n    }\n\n    @Test\n    public void anyMessage() {\n        final TestPipe pipe = new TestPipe(\"anyMessage\");\n\n        final AtomicReference<Message> firstMessage = new AtomicReference<>();\n\n        Bus.MESSAGE listener = (Bus bus, Message msg) -> {\n            firstMessage.compareAndSet(null, msg);\n            pipe.quit();\n        };\n\n        pipe.getBus().connect(listener);\n        pipe.play().run();\n        pipe.getBus().disconnect(listener);\n        pipe.dispose();\n\n        Message message = firstMessage.getAndSet(null);\n        assertNotNull(\"No message received\", message);\n        GCTracker gc = new GCTracker(message);\n        message = null;\n        assertTrue(\"Message not garbage collected\", gc.waitGC());\n        assertTrue(\"Message not destroyed\", gc.waitDestroyed());\n    }\n\n    @Test\n    public void postMessage() {\n        final TestPipe pipe = new TestPipe();\n\n        final AtomicBoolean signalFired = new AtomicBoolean(false);\n        final AtomicReference<GstObject> signalSource = new AtomicReference<>();\n        \n        Bus.MESSAGE listener = (Bus bus, Message msg) -> {\n            signalFired.set(true);\n            signalSource.set(msg.getSource());\n            pipe.quit();\n        };\n        \n        pipe.getBus().connect(listener);\n        Message message = new EOSMessage(pipe.src);\n        pipe.getBus().post(message);\n        pipe.run();\n        assertTrue(\"Message not posted\", signalFired.get());\n        assertEquals(\"Wrong source in message\", pipe.src, signalSource.get());\n        pipe.dispose();\n\n        GCTracker gc = new GCTracker(message);\n        message = null;\n        assertTrue(\"Message not garbage collected\", gc.waitGC());\n        assertTrue(\"Message not destroyed\", gc.waitDestroyed());\n    }\n\n    @Test\n    public void syncHandler() {\n        final TestPipe pipe = new TestPipe(\"syncHandler\");\n\n        final AtomicReference<Message> firstMessageSync = new AtomicReference<>();\n        final AtomicReference<Message> firstMessageAsync = new AtomicReference<>();\n\n        BusSyncHandler syncHandler = (Message message) -> {\n            firstMessageSync.compareAndSet(null, message);\n            return BusSyncReply.PASS;\n        };\n\n        Bus.MESSAGE listener = (Bus bus, Message msg) -> {\n            firstMessageAsync.compareAndSet(null, msg);\n            pipe.quit();\n        };\n\n        pipe.getBus().setSyncHandler(syncHandler);\n        pipe.getBus().connect(listener);\n        pipe.play().run();\n        pipe.getBus().disconnect(listener);\n        pipe.dispose();\n\n        Message message = firstMessageSync.getAndSet(null);\n        Message asyncMessage = firstMessageAsync.getAndSet(null);\n        assertNotNull(\"No message received\", message);\n        assertTrue(\"Sync and listeners messages not equal\", message == asyncMessage);\n        GCTracker gc = new GCTracker(message);\n        message = null;\n        asyncMessage = null;\n        assertTrue(\"Message not garbage collected\", gc.waitGC());\n        assertTrue(\"Message not destroyed\", gc.waitDestroyed());\n    }\n\n    @Test\n    public void syncHandlerRemoval() {\n        final TestPipe pipe = new TestPipe(\"syncHandlerRemoval\");\n\n        final AtomicReference<Message> firstMessageSync = new AtomicReference<>();\n        final AtomicReference<Message> firstMessageAsync = new AtomicReference<>();\n\n        BusSyncHandler syncHandler = (Message message) -> {\n            firstMessageSync.compareAndSet(null, message);\n            return BusSyncReply.PASS;\n        };\n\n        Bus.MESSAGE listener = (Bus bus, Message msg) -> {\n            firstMessageAsync.compareAndSet(null, msg);\n            pipe.quit();\n        };\n\n        pipe.getBus().setSyncHandler(syncHandler);\n        pipe.getBus().connect(listener);\n        pipe.getBus().setSyncHandler(null);\n        pipe.play().run();\n        pipe.getBus().disconnect(listener);\n        pipe.dispose();\n\n        assertNull(\"Removed sync handler received message\",\n                firstMessageSync.getAndSet(null));\n        Message message = firstMessageAsync.getAndSet(null);\n        assertNotNull(\"No message received\", message);\n        GCTracker gc = new GCTracker(message);\n        message = null;\n        assertTrue(\"Message not garbage collected\", gc.waitGC());\n        assertTrue(\"Message not destroyed\", gc.waitDestroyed());\n    }\n\n    @Test\n    public void listenerRemoval() {\n        final TestPipe pipe = new TestPipe(\"checkListenerRemoval\");\n\n        final AtomicReference<Message> firstMessage = new AtomicReference<>(null);\n        final AtomicBoolean stateChangedFired = new AtomicBoolean(false);\n\n        Bus.MESSAGE listener = (Bus bus, Message msg) -> {\n            firstMessage.compareAndSet(null, msg);\n            pipe.quit();\n        };\n\n        Bus.STATE_CHANGED stateListener = (GstObject source, State old, State current, State pending) -> {\n            stateChangedFired.set(true);\n        };\n\n        pipe.getBus().connect(listener);\n        pipe.getBus().connect(stateListener);\n        pipe.getBus().disconnect(stateListener);\n        pipe.play().run();\n        pipe.getBus().disconnect(listener);\n        pipe.dispose();\n\n        Message message = firstMessage.getAndSet(null);\n        assertNotNull(\"No message received\", message);\n\n        assertFalse(\"State changed fired after removal\", stateChangedFired.get());\n\n        GCTracker gc = new GCTracker(message);\n        message = null;\n        assertTrue(\"Message not garbage collected\", gc.waitGC());\n        assertTrue(\"Message not destroyed\", gc.waitDestroyed());\n    }\n\n    @Test\n    public void extendedMessageIssue202() {\n        final TestPipe pipe = new TestPipe(\"issue202\");\n\n        final AtomicBoolean signalFired = new AtomicBoolean(false);\n\n        Bus.MESSAGE msgListener = (Bus bus, Message msg) -> {\n            signalFired.set(true);\n        };\n\n        Bus.ERROR errListener = (GstObject source, int code, String message) -> {\n            // @TODO If used as flags, DEVICE_REMOVED and ERROR overlap.\n            // but an exception will be thrown in the executor and logged\n            // rather than this method being called - need a way to fail with\n            // executor exceptions in tests?\n        };\n\n        pipe.getBus().connect(errListener);\n        pipe.getBus().connect(msgListener);\n\n        for (Element elem : pipe.pipe.getSources()) {\n            GSTELEMENT_API.gst_element_post_message(elem,\n                    GSTMESSAGE_API\n                            .gst_message_new_custom(MessageType.DEVICE_REMOVED,\n                                    elem, null)\n            );\n        }\n        pipe.play().run();\n        pipe.getBus().disconnect(msgListener);\n        pipe.getBus().disconnect(errListener);\n\n        assertTrue(\"Custom message not received\", signalFired.get());\n        pipe.dispose();\n    }\n\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/CapsTest.java",
    "content": "/* \n * Copyright (c) 2007 Wayne Meissner\n * Copyright (C) 2005 Andy Wingo <wingo@pobox.com>\n * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertNotNull;\nimport static org.junit.Assert.assertTrue;\nimport static org.junit.Assert.fail;\n\nimport org.junit.AfterClass;\nimport org.junit.Assert;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\n/**\n * Unit test for GstCaps\n */\npublic class CapsTest {\n\n    public CapsTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(\"CapsTest\", new String[] {});\n    }\n    \n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n\n    @Test\n    public void capsMerge() {\n        Caps c1 = new Caps(\"video/x-raw, format=RGB, bpp=32, depth=24\");\n        Caps c2 = new Caps(\"video/x-raw, format=RGB, width=640, height=480\");\n        Caps c3 = Caps.merge(c1, c2);\n        // Verify that the victim caps were invalidated and cannot be used.\n        try {\n            c1.toString();\n            fail(\"merged caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        try {\n            c2.toString();\n            fail(\"merged caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        boolean widthFound = false, heightFound = false;\n        for (int i = 0; i < c3.size(); ++i) {\n            Structure s = c3.getStructure(i);\n            if (s.hasIntField(\"width\")) {\n                widthFound = true;\n            }\n            if (s.hasIntField(\"height\")) {\n                heightFound = true;\n            }\n        }\n        assertTrue(\"width not appended\", widthFound);\n        assertTrue(\"height not appended\", heightFound);\n        // Verify reference count before dispose\n        Assert.assertEquals(1, c3.getRefCount());\n        // Force cleanup to bring out any memory bugs\n        c3.dispose(); \n    }\n    \n    @Test\n    public void capsAppend() {\n        Caps c1 = new Caps(\"video/x-raw, format=RGB, bpp=32, depth=24\");\n        Caps c2 = new Caps(\"video/x-raw, format=RGB, width=640, height=480\");\n        c1.append(c2);\n        // Verify that the victim caps were invalidated and cannot be used.\n        try {\n            c2.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        boolean widthFound = false, heightFound = false;\n        for (int i = 0; i < c1.size(); ++i) {\n            Structure s = c1.getStructure(i);\n            if (s.hasIntField(\"width\")) {\n                widthFound = true;\n            }\n            if (s.hasIntField(\"height\")) {\n                heightFound = true;\n            }\n        }\n        assertTrue(\"width not appended\", widthFound);\n        assertTrue(\"height not appended\", heightFound);\n        // Verify reference count before dispose\n        Assert.assertEquals(1, c1.getRefCount());\n        // Force cleanup to bring out any memory bugs\n        c1.dispose(); \n    }\n    private static final String non_simple_caps_string =\n        \"video/x-raw, format=I420, framerate=(fraction)[ 1/100, 100 ], \"\n        + \"width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-raw, \"\n        + \"format=YUY2, framerate=(fraction)[ 1/100, 100 ], width=(int)[ 16, 4096 ], \"\n        + \"height=(int)[ 16, 4096 ]; video/x-raw, format=RGB, bpp=(int)8, depth=(int)8, \"\n        + \"endianness=(int)1234, framerate=(fraction)[ 1/100, 100 ], width=(int)[ 16, 4096 ], \"\n        + \"height=(int)[ 16, 4096 ]; video/x-raw, \"\n        + \"format={ I420, YUY2, YV12 }, width=(int)[ 16, 4096 ], \"\n        + \"height=(int)[ 16, 4096 ], framerate=(fraction)[ 1/100, 100 ]\";\n    @Test\n    public void simplify() {\n        Caps c1 = new Caps(non_simple_caps_string);\n        assertNotNull(\"Caps not created\", c1);\n        Caps c2 = c1.simplify();\n        assertNotNull(\"Simplify returned null\", c2);\n        /* check simplified caps, should be:\n         *\n         * video/x-raw, format=RGB, bpp=(int)8, depth=(int)8, endianness=(int)1234,\n         *     framerate=(fraction)[ 1/100, 100 ], width=(int)[ 16, 4096 ],\n         *     height=(int)[ 16, 4096 ];\n         * video/x-raw, format={ YV12, YUY2, I420 },\n         *     width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ],\n         *     framerate=(fraction)[ 1/100, 100 ]\n         */\n        assertEquals(\"Caps not simplified to 2 structures\", 2, c2.size());\n        Structure s1 = c2.getStructure(0);\n        assertNotNull(\"Caps.getStructure(0) failed\", s1);\n        Structure s2 = c2.getStructure(1);\n        assertNotNull(\"Caps.getStructure(1) failed\", s2);\n        if (!s1.hasName(\"video/x-raw\")) {\n            Structure tmp = s1;\n            s1 = s2;\n            s2 = tmp;\n        }\n        assertTrue(\"Could not locate video/x-raw structure\", s1.hasName(\"video/x-raw\"));\n        assertEquals(\"bpp not retrieved\", 8, s1.getInteger(\"bpp\"));\n        assertEquals(\"depth not retrieved\", 8, s1.getInteger(\"depth\"));\n        \n        assertTrue(\"Could not locate video/x-raw structure\", s2.hasName(\"video/x-raw\"));\n        \n        // Verify reference count before dispose\n        Assert.assertEquals(1, c1.getRefCount());\n        Assert.assertEquals(1, c2.getRefCount());\n        // Force cleanup to bring out any memory bugs\n        c1.dispose(); c2.dispose();\n    }\n    @Test\n    public void truncate() {\n\n        Caps c1 = Caps.fromString(non_simple_caps_string);\n        assertNotNull(\"Caps.fromString failed\", c1);\n        assertEquals(\"Incorrect number of structures in caps\", 4, c1.size());\n        Caps c2 = c1.truncate();\n        assertEquals(\"Caps not truncated\", 1, c2.size());\n        assertEquals(\"Original caps untouched\", 4, c1.size());\n        // Verify reference count before dispose\n        Assert.assertEquals(1, c1.getRefCount());\n        Assert.assertEquals(1, c2.getRefCount());\n        // Force cleanup to bring out any memory bugs\n        c1.dispose(); c2.dispose();\n    }\n    @Test\n    public void mergeANYAndSpecific() {\n        /* ANY + specific = ANY */\n        Caps c1 = Caps.anyCaps();\n        Caps c2 = Caps.fromString(\"audio/x-raw,rate=44100\");\n        Caps c3 = Caps.merge(c1, c2);\n        assertEquals(\"Too many structures in merged caps\", 0, c3.size());\n        assertTrue(\"Merged caps should be ANY\", c3.isAny());\n        // Verify that the victim caps were invalidated and cannot be used.\n        try {\n            c1.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        try {\n            c2.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        // Verify reference count before dispose\n        Assert.assertEquals(1, c3.getRefCount());\n        // Force cleanup to bring out any memory bugs\n        c3.dispose(); \n    }\n    @Test\n    public void mergeSpecificAndANY() {\n        /* specific + ANY = ANY */\n        Caps c1 = Caps.fromString(\"audio/x-raw,rate=44100\");\n        Caps c2 = Caps.anyCaps();\n        Caps c3 = Caps.merge(c1, c2);\n        assertEquals(\"Too many structures in merged caps\", 0, c3.size());\n        assertTrue(\"Merged caps should be ANY\", c3.isAny());\n        // Verify that the victim caps were invalidated and cannot be used.\n        try {\n            c1.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        try {\n            c2.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        // Verify reference count before dispose\n        Assert.assertEquals(1, c3.getRefCount());\n        // Force cleanup to bring out any memory bugs\n        c3.dispose(); \n    }\n    @Test\n    public void mergeSpecificAndEMPTY() {\n        /* specific + EMPTY = specific */\n        Caps c1 = Caps.fromString(\"audio/x-raw,rate=44100\");\n        Caps c2 = Caps.emptyCaps();\n        Caps c3 = Caps.merge(c1, c2);\n        assertEquals(\"Wrong number of structures in merged structure\", 1, c3.size());\n        assertFalse(\"Merged caps should not be empty\", c3.isEmpty());\n        // Verify that the victim caps were invalidated and cannot be used.\n        try {\n            c1.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        try {\n            c2.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        // Verify reference count before dispose\n        Assert.assertEquals(1, c3.getRefCount());\n        // Force cleanup to bring out any memory bugs\n        c3.dispose(); \n    }\n    @Test\n    public void mergeEMPTYAndSpecific() {\n        /* EMPTY + specific = specific */\n        Caps c1 = Caps.emptyCaps();\n        Caps c2 = Caps.fromString(\"audio/x-raw,rate=44100\");\n        Caps c3 = Caps.merge(c1, c2);\n        assertEquals(\"Merged Caps structure count incorrect\", 1, c3.size());\n        assertFalse(\"Merged caps should not be empty\", c3.isEmpty());\n        // Verify that the victim caps were invalidated and cannot be used.\n        try {\n            c1.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        try {\n            c2.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        // Verify reference count before dispose\n        Assert.assertEquals(1, c3.getRefCount());\n        // Force cleanup to bring out any memory bugs\n        c3.dispose(); \n    }\n    @Test \n    public void mergeSame() {\n        /* this is the same */\n        Caps c1 = Caps.fromString(\"audio/x-raw,rate=44100,channels=1\");\n        Caps c2 = Caps.fromString(\"audio/x-raw,rate=44100,channels=1\");\n        Caps c3 = Caps.merge(c1, c2);\n        assertEquals(\"Merged Caps structure count incorrect\", 1, c3.size());\n        // Verify that the victim caps were invalidated and cannot be used.\n        try {\n            c1.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        try {\n            c2.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        // Verify reference count before dispose\n        Assert.assertEquals(1, c3.getRefCount());\n        // Force cleanup to bring out any memory bugs\n        c3.dispose(); \n    }\n    @Test \n    public void mergeSameWithDifferentOrder() {\n        /* and so is this */\n        Caps c1 = Caps.fromString(\"audio/x-raw,rate=44100,channels=1\");\n        Caps c2 = Caps.fromString(\"audio/x-raw,channels=1,rate=44100\");\n        Caps c3 = Caps.merge(c1, c2);\n        assertEquals(\"Merged Caps structure count incorrect\", 1, c3.size());\n        // Verify that the victim caps were invalidated and cannot be used.\n        try {\n            c1.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        try {\n            c2.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        // Verify reference count before dispose\n        Assert.assertEquals(1, c3.getRefCount());\n        // Force cleanup to bring out any memory bugs\n        c3.dispose(); \n    }\n    @Test public void mergeSameWithBufferData() {\n        Caps c1 = Caps.fromString(\"video/x-foo, data=(buffer)AA\");\n        Caps c2 = Caps.fromString(\"video/x-foo, data=(buffer)AABB\");\n        Caps c3 = Caps.merge(c1, c2);\n        assertEquals(\"Merged Caps structure count incorrect\", 2, c3.size());\n        // Verify that the victim caps were invalidated and cannot be used.\n        try {\n            c1.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        try {\n            c2.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        // Verify reference count before dispose\n        Assert.assertEquals(1, c3.getRefCount());\n        // Force cleanup to bring out any memory bugs\n        c3.dispose(); \n    }\n    @Test public void mergeSameWithBufferDataReversed() {\n        Caps c1 = Caps.fromString(\"video/x-foo, data=(buffer)AABB\");\n        Caps c2 = Caps.fromString(\"video/x-foo, data=(buffer)AA\");\n        Caps c3 = Caps.merge(c1, c2);\n        assertEquals(\"Merged Caps structure count incorrect\", 2, c3.size());\n        // Verify that the victim caps were invalidated and cannot be used.\n        try {\n            c1.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        try {\n            c2.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        // Verify reference count before dispose\n        Assert.assertEquals(1, c3.getRefCount());\n        // Force cleanup to bring out any memory bugs\n        c3.dispose(); \n    }\n    @Test public void mergeSameWithBufferDataSame() {\n        Caps c1 = Caps.fromString(\"video/x-foo, data=(buffer)AA\");\n        Caps c2 = Caps.fromString(\"video/x-foo, data=(buffer)AA\");\n        Caps c3 = Caps.merge(c1, c2);\n        assertEquals(\"Merged Caps structure count incorrect\", 1, c3.size());\n        // Verify that the victim caps were invalidated and cannot be used.\n        try {\n            c1.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        try {\n            c2.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        // Verify reference count before dispose\n        Assert.assertEquals(1, c3.getRefCount());\n        // Force cleanup to bring out any memory bugs\n        c3.dispose(); \n    }\n    @Test public void mergeDifferentWithBufferDataSame() {\n        Caps c1 = Caps.fromString(\"video/x-foo, data=(buffer)AA\");\n        Caps c2 = Caps.fromString(\"video/x-bar, data=(buffer)AA\");\n        Caps c3 = Caps.merge(c1, c2);\n        assertEquals(\"Merged Caps structure count incorrect\", 2, c3.size());\n        // Verify that the victim caps were invalidated and cannot be used.\n        try {\n            c1.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        try {\n            c2.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        // Verify reference count before dispose\n        Assert.assertEquals(1, c3.getRefCount());\n        // Force cleanup to bring out any memory bugs\n        c3.dispose(); \n    }\n    @Test public void mergeSubset() {\n        /* the 2nd is already covered */\n        Caps c2 = Caps.fromString(\"audio/x-raw,channels=[1,2]\");\n        Caps c1 = Caps.fromString(\"audio/x-raw,channels=1\");\n        Caps c3 = Caps.merge(c1, c2).simplify();\n        System.out.println(c3.toString());\n        assertEquals(\"Merged Caps structure count incorrect\", 1, c3.size());\n        // Verify that the victim caps were invalidated and cannot be used.\n        try {\n            c1.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        try {\n            c2.toString();\n            fail(\"appended caps not invalidated\");\n        } catch (IllegalStateException ex) {}\n        // Verify reference count before dispose\n        Assert.assertEquals(1, c3.getRefCount());\n        // Force cleanup to bring out any memory bugs\n        c3.dispose(); \n    }\n    @Test public void intersect() {\n        Caps c2 = Caps.fromString(\"video/x-raw,format=I420,width=20\");\n        Caps c1 = Caps.fromString(\"video/x-raw,format=I420,height=30\");\n\n        Caps ci1 = c2.intersect(c1);\n        assertEquals(\"Intersected Caps structure count incorrect\", 1, ci1.size());\n        \n        Structure s = ci1.getStructure(0);\n        assertTrue(\"Incorrect name on intersected structure\", s.hasName(\"video/x-raw\"));\n        assertTrue(\"Intersected structure does not have 'format' field\", s.hasField(\"format\"));\n        assertTrue(\"Intersected structure does not have 'width' field\", s.hasField(\"width\"));\n        assertTrue(\"Intersected structure does not have 'height' field\", s.hasField(\"height\"));\n\n        /* with changed order */\n        Caps ci2 = c1.intersect(c2);\n        assertEquals(\"Intersected Caps structure count incorrect\", 1, ci2.size());\n        s = ci2.getStructure(0);\n        assertTrue(\"Incorrect name on intersected structure\", s.hasName(\"video/x-raw\"));\n        assertTrue(\"Intersected structure does not have 'format' field\", s.hasField(\"format\"));\n        assertTrue(\"Intersected structure does not have 'width' field\", s.hasField(\"width\"));\n        assertTrue(\"Intersected structure does not have 'height' field\", s.hasField(\"height\"));\n        \n        assertTrue(\"Intersection should be same in both directions\", ci1.isEqual(ci2));\n        // Force cleanup to bring out any memory bugs\n        c2.dispose(); c1.dispose(); ci1.dispose(); ci2.dispose();\n    }\n    @Test public void intersectUnspecified() {\n        /* field not specified = any value possible, so the intersection\n         * should keep fields which are only part of one set of caps */\n        Caps c2 = Caps.fromString(\"video/x-raw,format=I420,width=20\");\n        Caps c1 = Caps.fromString(\"video/x-raw,format=I420\");\n\n        Caps ci1 = c2.intersect(c1);\n        assertEquals(\"Intersected Caps structure count incorrect\", 1, ci1.size());\n        Structure s = ci1.getStructure(0);\n        assertTrue(\"Incorrect name on intersected structure\", s.hasName(\"video/x-raw\"));\n        assertTrue(\"Intersected structure does not have 'format' field\", s.hasField(\"format\"));\n        assertTrue(\"Intersected structure does not have 'width' field\", s.hasField(\"width\"));\n        \n        /* with changed order */\n\n        Caps ci2 = c1.intersect(c2);\n        assertEquals(\"Intersected Caps structure count incorrect\", 1, ci2.size());\n        s = ci2.getStructure(0);\n        assertTrue(\"Incorrect name on intersected structure\", s.hasName(\"video/x-raw\"));\n        assertTrue(\"Intersected structure does not have 'format' field\", s.hasField(\"format\"));\n        assertTrue(\"Intersected structure does not have 'width' field\", s.hasField(\"width\"));\n        assertTrue(\"Intersection should be same in both directions\", ci1.isEqual(ci2));\n        // Force cleanup to bring out any memory bugs\n        c2.dispose(); c1.dispose(); ci1.dispose(); ci2.dispose();\n    }\n    @Test public void intersectUnequal() {\n        Caps c2 = Caps.fromString(\"video/x-raw,format=I420,width=20\");\n        Caps c1 = Caps.fromString(\"video/x-raw,format=I420,width=30\");\n\n        Caps ci1 = c2.intersect(c1);\n        assertTrue(\"Intersection of unequal caps should be empty\", ci1.isEmpty());\n        /* with changed order */\n        Caps ci2 = c1.intersect(c2);\n        assertTrue(\"Intersection of unequal caps should be empty\", ci1.isEmpty());\n        assertTrue(\"Intersection should be same in both directions\", ci1.isEqual(ci2));\n        // Force cleanup to bring out any memory bugs\n        c2.dispose(); c1.dispose(); ci1.dispose(); ci2.dispose();\n    }\n    \n    @Test public void intersectDifferentType() {\n        Caps c2 = Caps.fromString(\"video/x-raw,format=I420,width=20\");\n        Caps c1 = Caps.fromString(\"video/x-raw,format=RGB,width=20\");\n\n        Caps ci1 = c2.intersect(c1);\n        assertTrue(\"Intersection of different type caps should be empty\", ci1.isEmpty());\n\n        /* with changed order */\n        Caps ci2 = c1.intersect(c2);\n        assertTrue(\"Intersection of different type caps should be empty\", ci1.isEmpty());\n        assertTrue(\"Intersection should be same in both directions\", ci1.isEqual(ci2));\n        // Force cleanup to bring out any memory bugs\n        c2.dispose(); c1.dispose(); ci1.dispose(); ci2.dispose();\n    }\n    \n}"
  },
  {
    "path": "test/org/freedesktop/gstreamer/ClockTest.java",
    "content": "/*\n * Copyright (c) 2020 Neil C Smith\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n *\n */\npackage org.freedesktop.gstreamer;\n\nimport org.junit.AfterClass;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n *\n */\npublic class ClockTest {\n    \n    @BeforeClass\n    public static void beforeClass() {\n        Gst.init(Gst.getVersion());\n    }\n\n    @AfterClass\n    public static void afterClass() {\n        Gst.deinit();\n    }\n    \n    @Test\n    public void calibrationTest() {\n        Pipeline pipe = (Pipeline) Gst.parseLaunch(\"autovideosrc ! autovideosink\");\n        Clock clock = pipe.getClock();\n        Clock.Calibration cal1 = clock.getCalibration();\n        System.out.println(cal1);\n        assertEquals(0, cal1.internal());\n        assertEquals(0, cal1.external());\n        assertEquals(1, cal1.rateNum());\n        assertEquals(1, cal1.rateDenom());\n        clock.setCalibration(-100, 1000, 8, 5);\n        \n        Clock.Calibration cal2 = clock.getCalibration();\n        System.out.println(cal2);\n        assertEquals(-100, cal2.internal());\n        assertEquals(1000, cal2.external());\n        assertEquals(8, cal2.rateNum());\n        assertEquals(5, cal2.rateDenom());\n        \n        Clock.Calibration cal3 = clock.getCalibration();\n        assertEquals(cal2, cal3);\n        assertEquals(cal2.hashCode(), cal3.hashCode());\n        assertNotEquals(cal1, cal3);\n        \n    }\n    \n    \n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/ClockTimeTest.java",
    "content": "/* \n * Copyright (c) 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport static org.junit.Assert.assertEquals;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\n/**\n *\n * @author wayne\n */\npublic class ClockTimeTest {\n\n    public ClockTimeTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n    }\n\n    @AfterClass\n    public static void tearDownClass() throws Exception {\n    }\n\n    @Before\n    public void setUp() {\n    }\n\n    @After\n    public void tearDown() {\n    }\n\n    @Test public void toSeconds() {\n        final long TIME = TimeUnit.SECONDS.toNanos(0xdeadbeef);\n        assertEquals(\"toSeconds returned incorrect value\", \n                TimeUnit.NANOSECONDS.toSeconds(TIME), ClockTime.toSeconds(TIME)); \n    }\n    @Test public void toMillis() {\n        final long TIME = TimeUnit.SECONDS.toNanos(0xdeadbeef);\n        assertEquals(\"toMillis returned incorrect value\", \n                TimeUnit.NANOSECONDS.toMillis(TIME), ClockTime.toMillis(TIME));        \n    }\n    @Test public void toMicros() {\n        final long TIME = TimeUnit.SECONDS.toNanos(0xdeadbeef);\n        assertEquals(\"toMillis returned incorrect value\", \n                TimeUnit.NANOSECONDS.toMicros(TIME), ClockTime.toMicros(TIME));\n    }\n    @Test public void toStringRepresentation() {\n        long hours = 3;\n        long minutes = 27;\n        long seconds = 13;\n        long time = TimeUnit.HOURS.toNanos(hours) +\n                TimeUnit.MINUTES.toNanos(minutes) +\n                TimeUnit.SECONDS.toNanos(seconds);\n        assertEquals(\"ClockTime.toString() incorrect\", \"03:27:13\", ClockTime.toString(time));\n    }\n//    @Test public void toNanos() {\n//        final long TIME = TimeUnit.SECONDS.toNanos(0xdeadbeef);\n//        ClockTime time = ClockTime.valueOf(TIME, TimeUnit.NANOSECONDS);\n//        assertEquals(\"toNanos returned incorrect value\", \n//                TimeUnit.NANOSECONDS.toNanos(TIME), time.toNanos());\n//        assertEquals(\"convertTo returned incorrect value\", \n//                TimeUnit.NANOSECONDS.toNanos(TIME), time.convertTo(TimeUnit.NANOSECONDS));\n//    }\n//    @Test public void compareTo() {\n//        // Collections.sort uses compareTo()\n//        List<ClockTime> list = new ArrayList<ClockTime>();\n//        list.add(ClockTime.valueOf(2, TimeUnit.SECONDS));\n//        list.add(ClockTime.valueOf(3, TimeUnit.SECONDS));\n//        list.add(ClockTime.valueOf(1, TimeUnit.SECONDS));\n//        Collections.sort(list);\n//        assertEquals(\"list not sorted correctly\", 1, list.get(0).toSeconds());\n//        assertEquals(\"list not sorted correctly\", 2, list.get(1).toSeconds());\n//        assertEquals(\"list not sorted correctly\", 3, list.get(2).toSeconds());\n//    }\n//    \n}"
  },
  {
    "path": "test/org/freedesktop/gstreamer/ContextTest.java",
    "content": "package org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GstContextAPI;\nimport org.freedesktop.gstreamer.lowlevel.GstContextPtr;\nimport org.junit.AfterClass;\nimport org.junit.Assert;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\npublic class ContextTest {\n\n\t@BeforeClass\n\tpublic static void setUpClass() throws Exception {\n\t\tGst.init(\"test\");\n\t}\n\n\t@AfterClass\n\tpublic static void tearDownClass() throws Exception {\n\t\tGst.deinit();\n\t}\n\n\t@Test\n\tpublic void testConstruction() {\n\t\tGstContextAPI contextApi = GstContextAPI.GSTCONTEXT_API;\n\t\tString contextType = \"whatever\";\n\t\ttry (Context context = new Context(contextType)) {\n\t\t\tGstContextPtr gstContextPtr = Natives.getPointer(context).as(GstContextPtr.class, GstContextPtr::new);\n\n\t\t\t// Context type.\n\t\t\tAssert.assertEquals(contextType, context.getContextType());\n\t\t\tAssert.assertTrue(contextApi.gst_context_has_context_type(gstContextPtr, contextType));\n\t\t\tAssert.assertFalse(contextApi.gst_context_has_context_type(gstContextPtr, contextType + \".something-else\"));\n\n\t\t\t// Default is persistent.\n\t\t\tAssert.assertTrue(contextApi.gst_context_is_persistent(gstContextPtr));\n\n\t\t\tAssert.assertNotNull(context.getWritableStructure());\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/ElementFactoryTest.java",
    "content": "/* \n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertNotNull;\nimport static org.junit.Assert.assertTrue;\n\nimport java.lang.ref.WeakReference;\nimport java.util.List;\n\nimport org.freedesktop.gstreamer.ElementFactory.ListType;\nimport org.freedesktop.gstreamer.PluginFeature.Rank;\nimport org.freedesktop.gstreamer.elements.DecodeBin;\nimport org.freedesktop.gstreamer.elements.PlayBin;\nimport org.freedesktop.gstreamer.elements.URIDecodeBin;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Ignore;\nimport org.junit.Test;\n\n/**\n *\n * @author wayne\n */\n@SuppressWarnings(\"deprecation\")\npublic class ElementFactoryTest {\n    \n    public ElementFactoryTest() {\n    }\n    \n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(\"test\", new String[] {});\n    }\n    \n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n    \n    @Before\n    public void setUp() throws Exception {\n    }\n    \n    @After\n    public void tearDown() throws Exception {\n    }\n    @Test\n    public void testMakeFakesink() {\n        Element e = ElementFactory.make(\"fakesink\", \"sink\");\n        assertNotNull(\"Failed to create fakesink\", e);\n    }\n    @Test\n    public void testMakeFakesrc() {\n        Element e = ElementFactory.make(\"fakesrc\", \"source\");\n        assertNotNull(\"Failed to create fakesrc\", e);\n    }\n    @Test\n    public void testMakeFilesink() {\n        Element e = ElementFactory.make(\"filesink\", \"sink\");\n        assertNotNull(\"Failed to create filesink\", e);\n    }\n    @Test\n    public void testMakeFilesrc() {\n        Element e = ElementFactory.make(\"filesrc\", \"source\");\n        assertNotNull(\"Failed to create filesrc\", e);\n    }\n    @Test\n    public void testMakeBin() {\n        Element e = ElementFactory.make(\"bin\", \"bin\");\n        assertNotNull(\"Failed to create bin\", e);\n        assertTrue(\"Element not a subclass of Bin\", e instanceof Bin);\n    }\n    @Test\n    public void testMakePipeline() {\n        Element e = ElementFactory.make(Pipeline.GST_NAME, \"bin\");\n        assertNotNull(\"Failed to create \" + Pipeline.GST_NAME, e);\n        assertTrue(\"Element not a subclass of Bin\", e instanceof Bin);\n        assertTrue(\"Element not a subclass of Pipeline\", e instanceof Pipeline);\n    }\n    @Test\n    public void testMakePlaybin() {\n        Element e = ElementFactory.make(PlayBin.GST_NAME, \"bin\");\n        assertNotNull(\"Failed to create \" + PlayBin.GST_NAME, e);\n        assertTrue(\"Element not a subclass of Bin\", e instanceof Bin);\n        assertTrue(\"Element not a subclass of Pipeline\", e instanceof Pipeline);\n        assertTrue(\"Element not a subclass of PlayBin\", e instanceof PlayBin);\n    }\n    @Test\n    public void testMakeDecodeBin() {\n        Element e = ElementFactory.make(DecodeBin.GST_NAME, \"bin\");\n        assertNotNull(\"Failed to create \" + DecodeBin.GST_NAME, e);\n        assertTrue(\"Element not a subclass of Bin\", e instanceof Bin);\n        assertTrue(\"Element not a subclass of DecodeBin\", e instanceof DecodeBin);\n    }\n    @Test\n    public void testMakeURIDecodeBin() {\n        Element e = ElementFactory.make(URIDecodeBin.GST_NAME, \"bin\");\n        assertNotNull(\"Failed to create \" + URIDecodeBin.GST_NAME, e);\n        assertTrue(\"Element not a subclass of Bin\", e instanceof Bin);\n        assertTrue(\"Element not a subclass of DecodeBin\", e instanceof URIDecodeBin);\n    }\n    @Test\n    public void testCreateFakesrc() {\n        ElementFactory factory = ElementFactory.find(\"fakesrc\");\n        assertNotNull(\"Could not locate fakesrc factory\", factory);\n        Element e = factory.create(\"source\");\n        assertNotNull(\"Failed to create fakesrc\", e);\n    }\n    @Test\n    public void testCreateBin() {\n        ElementFactory factory = ElementFactory.find(\"bin\");\n        assertNotNull(\"Could not locate bin factory\", factory);\n        Element e = factory.create(\"bin\");\n        assertNotNull(\"Failed to create bin\", e);\n        assertTrue(\"Element not a subclass of Bin\", e instanceof Bin);\n    }\n    @Test\n    public void testCreatePipeline() {\n        ElementFactory factory = ElementFactory.find(\"pipeline\");\n        assertNotNull(\"Could not locate pipeline factory\", factory);\n        Element e = factory.create(\"bin\");\n        assertNotNull(\"Failed to create pipeline\", e);\n        assertTrue(\"Element not a subclass of Bin\", e instanceof Bin);\n        assertTrue(\"Element not a subclass of Pipeline\", e instanceof Pipeline);\n    }\n    @Test\n    public void testCreatePlaybin() {\n        ElementFactory factory = ElementFactory.find(\"playbin\");\n        assertNotNull(\"Could not locate pipeline factory\", factory);\n        System.out.println(\"PlayBin factory name=\" + factory.getName());\n        Element e = factory.create(\"bin\");\n        assertNotNull(\"Failed to create playbin\", e);\n        assertTrue(\"Element not a subclass of Bin\", e instanceof Bin);\n        assertTrue(\"Element not a subclass of Pipeline\", e instanceof Pipeline);\n        assertTrue(\"Element not a subclass of PlayBin\", e instanceof PlayBin);\n    }\n    @Test\n    public void testGarbageCollection() throws Throwable {\n        ElementFactory factory = ElementFactory.find(\"fakesrc\");\n        assertNotNull(\"Could not locate fakesrc factory\", factory);\n        WeakReference<ElementFactory> ref = new WeakReference<ElementFactory>(factory);\n        factory = null;\n        assertTrue(\"Factory not garbage collected\", GCTracker.waitGC(ref));\n    }\n    @Test\n    public void testMakeGarbageCollection() throws Throwable {\n        Element e = ElementFactory.make(\"fakesrc\", \"test\");\n        WeakReference<Element> ref = new WeakReference<Element>(e);\n        e = null;\n        assertTrue(\"Element not garbage collected\", GCTracker.waitGC(ref));\n        \n    }\n    @Test\n    public void testCreateGarbageCollection() throws Throwable {\n        ElementFactory factory = ElementFactory.find(\"fakesrc\");\n        assertNotNull(\"Could not locate fakesrc factory\", factory);\n        Element e = factory.create(\"bin\");\n        WeakReference<Element> ref = new WeakReference<Element>(e);\n        e = null;\n        assertTrue(\"Element not garbage collected\", GCTracker.waitGC(ref));\n    }\n    @Test\n    public void getStaticPadTemplates() {\n        ElementFactory f = ElementFactory.find(\"fakesink\");\n        List<StaticPadTemplate> templates = f.getStaticPadTemplates();\n        assertTrue(\"No static pad templates found\", !templates.isEmpty());\n        StaticPadTemplate t = templates.get(0);\n        assertEquals(\"Not a sink\", \"sink\", t.getName());\n        assertEquals(\"Not a sink\", PadDirection.SINK, t.getDirection());\n    }\n\n    @Test\n    public void listGetElement() {\n        List<ElementFactory> list = ElementFactory.listGetElements(ListType.ANY,\n                Rank.NONE);\n        assertNotNull(\"List of factories is null\", list);\n        assertTrue(\"No factories found\", !list.isEmpty());\n//        System.out.println(\"Factories >>>\");\n//        for (ElementFactory fact : list) {\n//            System.out.println(fact.getName());\n//        }\n//        System.out.println(\"<<<\");\n    }\n\n//    @Test\n//    public void filterList() {\n//        List<ElementFactory> list = ElementFactory.listGetElements(ListType.ENCODER,\n//                Rank.NONE);\n//        assertNotNull(\"List of factories is null\", list);\n//        assertTrue(\"No factories found\", !list.isEmpty());\n//        List<ElementFactory> filterList = ElementFactory.listFilter(list, new Caps(\"video/x-h263\"),\n//                PadDirection.SRC, false);\n//\n//        assertNotNull(\"List of factories is null\", filterList);\n//        assertTrue(\"No factories found\", !filterList.isEmpty());\n////        System.out.println(\"Filtered factories >>>\");\n////        for (ElementFactory fact : filterList) {\n////            System.out.println(fact.getName());\n////        }\n////        System.out.println(\"<<<\");\n//    }\n\n    @Test\n    public void filterList2() {\n        List<ElementFactory> list = ElementFactory.listGetElementsFilter(ListType.ENCODER, Rank.NONE, new Caps(\"video/x-h263\"),\n                PadDirection.SRC, false);\n        assertNotNull(\"List of factories is null\", list);\n        assertTrue(\"No factories found\", !list.isEmpty());\n\n//        System.out.println(\"Factories >>>\");\n//        for (ElementFactory fact : list) {\n//            System.out.println(fact.getName());\n//        }\n//        System.out.println(\"<<<\");\n    }\n    \n    @Test\n    public void testMetaData() {\n        ElementFactory f = ElementFactory.find(\"fakesink\");\n        String klass = f.getKlass();\n        String longName = f.getLongName();\n        String description = f.getDescription();\n        String author = f.getAuthor();\n        assertNotNull(\"Klass is null\", klass);\n        assertNotNull(\"Long name is null\", longName);\n        assertNotNull(\"Description is null\", description);\n        assertNotNull(\"Author is null\", author);\n        System.out.println(\"FakeSink MetaData\");\n        System.out.println(\"Klass : \" + f.getKlass());\n        System.out.println(\"Long Name : \" + f.getLongName());\n        System.out.println(\"Description : \" + f.getDescription());\n        System.out.println(\"Author : \" + f.getAuthor());\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/ElementTest.java",
    "content": "/* \n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertTrue;\n\nimport java.util.List;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport org.freedesktop.gstreamer.glib.Natives;\n\nimport org.freedesktop.gstreamer.message.Message;\nimport org.freedesktop.gstreamer.message.TagMessage;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Assert;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\n/**\n *\n * @author wayne\n */\npublic class ElementTest {\n\n    public ElementTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(\"ElementTest\", new String[] {});\n    }\n    \n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n\n    @Before\n    public void setUp() {\n    }\n\n    @After\n    public void tearDown() {\n    }\n\n    // TODO add test methods here.\n    // The methods must be annotated with annotation @Test. For example:\n    //\n    // @Test\n    // public void hello() {}\n    @Test\n    public void getPads() {\n        Element element = ElementFactory.make(\"fakesink\", \"fs\");\n        List<Pad> pads = element.getPads();\n        assertTrue(\"no pads found\", !pads.isEmpty());\n    }\n    @Test\n    public void getSinkPads() {\n        Element element = ElementFactory.make(\"fakesink\", \"fs\");\n        List<Pad> pads = element.getSinkPads();\n        assertTrue(\"no pads found\", !pads.isEmpty());\n    }\n    @Test\n    public void getSrcPads() {\n        Element element = ElementFactory.make(\"fakesrc\", \"fs\");\n        List<Pad> pads = element.getSrcPads();\n        assertTrue(\"no pads found\", !pads.isEmpty());\n    }\n    @Test \n    public void setState() {\n        Element element = ElementFactory.make(\"fakesrc\", \"fs\");\n        // This should exercise EnumMapper.intValue()\n        element.play();\n        element.stop();\n    }\n    @Test \n    public void getState() {\n        Element element = ElementFactory.make(\"fakesrc\", \"fs\");\n        // This should exercise EnumMapper.intValue()\n        element.play();\n        State state = element.getState(-1);\n        assertEquals(\"Element state not set correctly\", State.PLAYING, state);\n        element.stop();\n    }\n    @Test public void postMessage() {\n        final TestPipe pipe = new TestPipe();\n        final AtomicBoolean signalFired = new AtomicBoolean(false);\n        //\n        // Use a TagMessage, since it is the only type that doesn't get intercepted \n        // by the pipeline\n        //\n        final Message message = new TagMessage(pipe.src, new TagList());\n        pipe.getBus().connect(new Bus.MESSAGE() {\n\n            public void busMessage(Bus bus, Message msg) {\n                if (msg.equals(message)) {\n                    signalFired.set(true);\n                    pipe.quit();\n                }\n            }\n        });\n        pipe.sink.postMessage(message);\n        pipe.run();\n        assertTrue(\"Message not posted\", signalFired.get());\n    }\n    @Test public void testContext() {\n        Element element = ElementFactory.make(\"fakesrc\", \"fs\");\n        Assert.assertEquals(1, element.getRefCount());\n        \n        Context context = new Context(\"test\");\n        Assert.assertEquals(1, context.getRefCount());\n        element.setContext(context);\n        Assert.assertEquals(2, context.getRefCount());\n        \n        Context anotherContext = element.getContext(\"test\");\n        Assert.assertEquals(2, anotherContext.getRefCount());\n        Assert.assertNotNull(anotherContext);\n        Assert.assertEquals(context.getContextType(), anotherContext.getContextType());\n        \n        Assert.assertNull(element.getContext(\"test-something-else\"));\n        \n        element.dispose();\n        Assert.assertEquals(0, element.getRefCount());\n        Assert.assertEquals(1, context.getRefCount());\n        Assert.assertEquals(1, anotherContext.getRefCount());\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/EnumTest.java",
    "content": "/* \n * Copyright (c) 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport static org.junit.Assert.assertEquals;\n\nimport org.freedesktop.gstreamer.lowlevel.EnumMapper;\nimport org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\n/**\n *\n * @author wayne\n */\npublic class EnumTest {\n\n    public EnumTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(\"EnumTest\", new String[] {});\n    }\n    \n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n\n    @Before\n    public void setUp() {\n    }\n\n    @After\n    public void tearDown() {\n    }\n    private static enum TestEnum {\n        FOO,\n        @DefaultEnumValue\n        BAR;\n    }\n    // TODO add test methods here.\n    // The methods must be annotated with annotation @Test. For example:\n    //\n    // @Test\n    // public void hello() {}\n    @Test public void valueOfInt() {\n        TestEnum e = EnumMapper.getInstance().valueOf(0xdeadbeef, TestEnum.class);\n        assertEquals(\"Wrong value returned for the default\", TestEnum.BAR, e);\n    }\n}"
  },
  {
    "path": "test/org/freedesktop/gstreamer/ExecutorServiceTest.java",
    "content": "/* \n * Copyright (c) 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertTrue;\n\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.Future;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport org.freedesktop.gstreamer.glib.MainContextExecutorService;\nimport org.freedesktop.gstreamer.lowlevel.MainLoop;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\n/**\n *\n * @author wayne\n */\npublic class ExecutorServiceTest {\n\n    public ExecutorServiceTest() {\n    }\n    private static MainLoop loop;\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(\"ExecutorServiceTest\", new String[] {});\n        (loop = new MainLoop()).startInBackground();\n    }\n    \n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        loop.quit();\n        Gst.deinit();\n    }\n\n    @Before\n    public void setUp() {\n    }\n\n    @After\n    public void tearDown() {\n    }\n    private static class TestExec {\n        private final CountDownLatch latch = new CountDownLatch(1);\n        final MainContextExecutorService exec = new MainContextExecutorService(Gst.getMainContext());\n        final AtomicBoolean fired = new AtomicBoolean(false);\n        public TestExec run() { \n            // Create a timer to quit out of the test so it does not hang\n            try {\n                latch.await(250, TimeUnit.MILLISECONDS);\n            } catch (Exception ex) {}\n            return this;\n        }\n        public void execute(Runnable run) {\n            exec.execute(run);\n        }\n        public void quit() {\n            latch.countDown();\n        }\n        public void fired() {\n            fired.set(true);\n            quit();\n        }\n        public boolean hasFired() {\n            return fired.get();\n        }\n    }\n    \n    @Test public void execute() {\n        final TestExec exec = new TestExec();\n        exec.execute(new Runnable() {\n\n            public void run() {\n                exec.fired();\n            }\n        });\n        exec.run();\n        assertTrue(\"Runnable not called\", exec.hasFired());\n    }\n    @Test public void submit() throws Exception {\n        final TestExec exec = new TestExec();\n        final Integer MAGIC = 0xdeadbeef;\n        Callable<Integer> callable = new Callable<Integer>() {\n\n            public Integer call() throws Exception {\n                exec.fired();\n                return MAGIC;\n            }\n        };\n        Future<Integer> f = exec.exec.submit(callable);\n        exec.run();\n        assertTrue(\"Callable not called\", exec.hasFired());\n        assertEquals(\"Wrong value returned from Callable\", MAGIC, f.get());\n        \n    }\n    @Test public void oneShotTimeout() {\n        final TestExec exec = new TestExec();\n        exec.exec.schedule(new Runnable() {\n\n            public void run() {\n                exec.fired();\n            }\n        }, 100, TimeUnit.MILLISECONDS);\n        \n        exec.run();\n        assertTrue(\"Runnable not called\", exec.hasFired());\n    }\n    @Test public void timeoutWithReturnValue() throws Exception {\n        final TestExec exec = new TestExec();\n        final Integer MAGIC = 0xdeadbeef;\n        Callable<Integer> callable = new Callable<Integer>() {\n\n            public Integer call() throws Exception {\n                exec.fired();\n                return MAGIC;\n            }\n        };\n        Future<Integer> f = exec.exec.schedule(callable, 100, TimeUnit.MILLISECONDS);\n        \n        exec.run();\n        assertTrue(\"Runnable not called\", exec.hasFired());\n        assertEquals(\"Wrong value returned from Callable\", MAGIC, f.get());\n    }\n    @Test public void periodicTimeout() {\n        final TestExec exec = new TestExec();\n        final AtomicBoolean called = new AtomicBoolean(false);\n        exec.exec.scheduleAtFixedRate(new Runnable() {\n\n            public void run() {\n                if (called.getAndSet(true)) {\n                    exec.fired();\n                }\n            }\n        }, 10, 10, TimeUnit.MILLISECONDS);\n        \n        exec.run();\n        assertTrue(\"Runnable not called\", exec.hasFired());\n    }\n}"
  },
  {
    "path": "test/org/freedesktop/gstreamer/GCTracker.java",
    "content": "/* \n * Copyright (C) 2020 Neil C Smith\n * Copyright (C) 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport java.lang.ref.WeakReference;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport com.sun.jna.Pointer;\nimport org.freedesktop.gstreamer.glib.GObject;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GstMiniObjectPtr;\nimport org.freedesktop.gstreamer.lowlevel.IntPtr;\n\nimport static org.freedesktop.gstreamer.lowlevel.GObjectAPI.*;\nimport static org.freedesktop.gstreamer.lowlevel.GstMiniObjectAPI.*;\n\n/**\n * Tracks Java and/or native disposal of GObject and MiniObject derived objects.\n */\npublic class GCTracker {\n\n    private static final Map<Integer, WeakReference<GCTracker>> OBJ_MAP\n            = Collections.synchronizedMap(new HashMap<Integer, WeakReference<GCTracker>>());\n\n    private final WeakReference<?> ref;\n    private final AtomicBoolean destroyed = new AtomicBoolean(false);\n\n    public GCTracker(GObject obj) {\n        int identityHashCode = System.identityHashCode(this);\n        ref = new WeakReference<>(obj);\n        OBJ_MAP.put(identityHashCode, new WeakReference<>(this));\n        GOBJECT_API.g_object_weak_ref(obj, GOBJECT_NOTIFY, new IntPtr(identityHashCode));\n    }\n    \n    public GCTracker(MiniObject obj) {\n        int identityHashCode = System.identityHashCode(this);\n        ref = new WeakReference<>(obj);\n        OBJ_MAP.put(identityHashCode, new WeakReference<>(this));\n        GSTMINIOBJECT_API.gst_mini_object_weak_ref(\n                Natives.getPointer(obj).as(GstMiniObjectPtr.class, GstMiniObjectPtr::new),\n                GSTMINIOBJECT_NOTIFY,\n                new IntPtr(identityHashCode));\n    }\n\n    public boolean waitGC() {\n        return waitGC(ref);\n    }\n\n    public boolean waitDestroyed() {\n        for (int i = 0; !destroyed.get() && i < 10; ++i) {\n            try {\n                Thread.sleep(100);\n            } catch (InterruptedException ex) {\n            }\n        }\n        return destroyed.get();\n    }\n\n    private static final GWeakNotify GOBJECT_NOTIFY = new GWeakNotify() {\n\n        @Override\n        public void callback(IntPtr id, Pointer obj) {\n            int identityHashCode = id.intValue();\n            WeakReference<GCTracker> trackerRef = OBJ_MAP.get(identityHashCode);\n            GCTracker tracker = trackerRef.get();\n            if (tracker != null) {\n                tracker.destroyed.set(true);\n            }\n        }\n    };\n\n    private static final GstMiniObjectNotify GSTMINIOBJECT_NOTIFY\n            = new GstMiniObjectNotify() {\n\n        @Override\n        public void callback(IntPtr id, Pointer obj) {\n            int identityHashCode = id.intValue();\n            WeakReference<GCTracker> trackerRef = OBJ_MAP.get(identityHashCode);\n            GCTracker tracker = trackerRef.get();\n            if (tracker != null) {\n                tracker.destroyed.set(true);\n            }\n        }\n    };\n\n    public static boolean waitGC(WeakReference<? extends Object> ref) {\n        System.gc();\n        for (int i = 0; ref.get() != null && i < 10; ++i) {\n            try {\n                Thread.sleep(10);\n            } catch (InterruptedException ex) {\n            }\n            System.gc();\n        }\n        return ref.get() == null;\n    }\n\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/GLibTest.java",
    "content": "/* \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.GLib;\nimport static org.junit.Assert.assertEquals;\nimport org.junit.Test;\n\npublic class GLibTest {\n    \n    @Test\n    public void getEnv() {       \n        String user = GLib.getEnv(\"USER\");\n        String pwd = GLib.getEnv(\"PWD\");\n        System.out.println(\"user: \" + user);\n        System.out.println(\"path: \" + pwd);        \n    }\n    \n    @Test\n    public void setUnsetEnv() {\n        \n        // set environment\n        GLib.setEnv(\"TESTVAR\", \"foo\", true);\n        \n        // get environment\n        assertEquals(\"could not set TESTVAR!\", GLib.getEnv(\"TESTVAR\"), \"foo\");\n        \n        // unset\n        GLib.unsetEnv(\"TESTVAR\");\n        assertEquals(\"could not unset TESTVAR!\", GLib.getEnv(\"TESTVAR\"), null);\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/GarbageCollectionEDTTest.java",
    "content": "/* \n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport java.lang.ref.WeakReference;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertTrue;\n\n/**\n *\n */\npublic class GarbageCollectionEDTTest {\n\n    public GarbageCollectionEDTTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        System.setProperty(\"glib.reapOnEDT\", \"true\");\n        Gst.init(\"test\", new String[]{});\n    }\n\n    @AfterClass\n    public static void tearDownClass() throws Exception {\n//        Gst.deinit();\n    }\n\n    @Before\n    public void setUp() throws Exception {\n    }\n\n    @After\n    public void tearDown() throws Exception {\n    }\n\n    @Test\n    public void testElement() throws Exception {\n\n        Element e = ElementFactory.make(\"fakesrc\", \"test element\");\n        GCTracker tracker = new GCTracker(e);\n        e = null;\n        assertTrue(\"Element not garbage collected\", tracker.waitGC());\n        assertTrue(\"GObject not destroyed\", tracker.waitDestroyed());\n    }\n\n    @Test\n    public void testBin() throws Exception {\n        Bin bin = new Bin(\"test\");\n        Element e1 = ElementFactory.make(\"fakesrc\", \"source\");\n        Element e2 = ElementFactory.make(\"fakesink\", \"sink\");\n        bin.addMany(e1, e2);\n\n        assertEquals(\"source not returned\", e1, bin.getElementByName(\"source\"));\n        assertEquals(\"sink not returned\", e2, bin.getElementByName(\"sink\"));\n        WeakReference<Element> binRef = new WeakReference<Element>(bin);\n        bin = null;\n        assertTrue(\"Bin not garbage collected\", GCTracker.waitGC(binRef));\n        WeakReference<Element> e1Ref = new WeakReference<Element>(e1);\n        WeakReference<Element> e2Ref = new WeakReference<Element>(e2);\n        e1 = null;\n        e2 = null;\n\n        assertTrue(\"First Element not garbage collected\", GCTracker.waitGC(e1Ref));\n        assertTrue(\"Second Element not garbage collected\", GCTracker.waitGC(e2Ref));\n\n    }\n\n    @Test\n    public void testBinRetrieval() throws Exception {\n        Bin bin = new Bin(\"test\");\n        Element e1 = ElementFactory.make(\"fakesrc\", \"source\");\n        Element e2 = ElementFactory.make(\"fakesink\", \"sink\");\n        bin.addMany(e1, e2);\n        int id1 = System.identityHashCode(e1);\n        int id2 = System.identityHashCode(e2);\n\n        e1 = null;\n        e2 = null;\n        System.gc();\n        Thread.sleep(10);\n        // Should return the same object that was put into the bin\n        assertEquals(\"source ID does not match\", id1, System.identityHashCode(bin.getElementByName(\"source\")));\n        assertEquals(\"sink ID does not match\", id2, System.identityHashCode(bin.getElementByName(\"sink\")));\n    }\n\n    @Test\n    public void pipeline() {\n        Pipeline pipe = new Pipeline(\"test\");\n        GCTracker pipeTracker = new GCTracker(pipe);\n        pipe = null;\n        assertTrue(\"Pipe not garbage collected\", pipeTracker.waitGC());\n        System.out.println(\"checking if pipeline is destroyed\");\n        assertTrue(\"Pipe not destroyed\", pipeTracker.waitDestroyed());\n    }\n\n    @Test\n    public void pipelineBus() {\n        Pipeline pipe = new Pipeline(\"test\");\n        Bus bus = pipe.getBus();\n        GCTracker busTracker = new GCTracker(bus);\n        GCTracker pipeTracker = new GCTracker(pipe);\n\n        pipe = null;\n        bus = null;\n        assertTrue(\"Bus not garbage collected\", busTracker.waitGC());\n        assertTrue(\"Bus not destroyed\", busTracker.waitDestroyed());\n        assertTrue(\"Pipe not garbage collected\", pipeTracker.waitGC());\n        assertTrue(\"Pipe not destroyed\", pipeTracker.waitDestroyed());\n\n    }\n\n    @Test\n    public void busWithListeners() {\n        Pipeline pipe = new Pipeline(\"test\");\n        Bus bus = pipe.getBus();\n        bus.connect(new Bus.EOS() {\n\n            public void endOfStream(GstObject source) {\n            }\n        });\n\n        GCTracker busTracker = new GCTracker(bus);\n        GCTracker pipeTracker = new GCTracker(pipe);\n        bus = null;\n        pipe = null;\n        assertTrue(\"Bus not garbage collected\", busTracker.waitGC());\n        assertTrue(\"Bus not destroyed\", busTracker.waitDestroyed());\n        assertTrue(\"Pipe not garbage collected\", pipeTracker.waitGC());\n        assertTrue(\"Pipe not destroyed\", pipeTracker.waitDestroyed());\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/GarbageCollectionTest.java",
    "content": "/* \n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertTrue;\n\nimport java.lang.ref.WeakReference;\nimport java.util.List;\n\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Ignore;\nimport org.junit.Test;\n\n/**\n *\n * @author wayne\n */\npublic class GarbageCollectionTest {\n    \n    public GarbageCollectionTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(\"test\", new String[] {});\n    }\n    \n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n\n    @Before\n    public void setUp() throws Exception {\n    }\n\n    @After\n    public void tearDown() throws Exception {\n    }\n\n    @Test\n    public void testElement() throws Exception {\n        \n        Element e = ElementFactory.make(\"fakesrc\", \"test element\");\n        GCTracker tracker = new GCTracker(e);\n        e = null;        \n        assertTrue(\"Element not garbage collected\", tracker.waitGC());        \n        assertTrue(\"GObject not destroyed\", tracker.waitDestroyed());\n    }\n    @Test\n    public void testBin() throws Exception {\n        Bin bin = new Bin(\"test\");\n        Element e1 = ElementFactory.make(\"fakesrc\", \"source\");\n        Element e2 = ElementFactory.make(\"fakesink\", \"sink\");\n        bin.addMany(e1, e2);\n        \n        assertEquals(\"source not returned\", e1, bin.getElementByName(\"source\"));\n        assertEquals(\"sink not returned\", e2, bin.getElementByName(\"sink\"));\n        GCTracker binTracker = new GCTracker(bin);\n        bin = null;\n        assertTrue(\"Bin not garbage collected\", binTracker.waitGC());\n        assertTrue(\"Bin not destroyed\", binTracker.waitDestroyed());\n        GCTracker e1Tracker = new GCTracker(e1);\n        GCTracker e2Tracker = new GCTracker(e2);\n        e1 = null;\n        e2 = null;\n        \n        assertTrue(\"First Element not garbage collected\", e1Tracker.waitGC());\n        assertTrue(\"First Element not destroyed\", e1Tracker.waitDestroyed());\n        assertTrue(\"Second Element not garbage collected\", e2Tracker.waitGC());\n        assertTrue(\"Second Element not destroyed\", e2Tracker.waitDestroyed());\n        \n    }\n    \n    @Test\n    public void testBinParsed() throws Exception {\n        Bin bin = Gst.parseBinFromDescription(\"fakesrc name=source ! fakesink name=sink\", false);\n        int binRefCount = bin.getRefCount();\n        List<Element> children = bin.getElements();\n        assertEquals(\"Iteration increased Bin refcount\", binRefCount, bin.getRefCount());\n        assertEquals(\"Wrong number of child elements\", 2, children.size());\n        Element e1 = children.get(0);\n        Element e2 = children.get(1);\n        GCTracker binTracker = new GCTracker(bin);\n        bin = null;\n        assertTrue(\"Bin not garbage collected\", binTracker.waitGC());\n        assertTrue(\"Bin not destroyed\", binTracker.waitDestroyed());\n        GCTracker e1Tracker = new GCTracker(e1);\n        GCTracker e2Tracker = new GCTracker(e2);\n        children = null;\n        e1 = null;\n        e2 = null;\n        \n        assertTrue(\"First Element not garbage collected\", e1Tracker.waitGC());\n        assertTrue(\"First Element not destroyed\", e1Tracker.waitDestroyed());\n        assertTrue(\"Second Element not garbage collected\", e2Tracker.waitGC());\n        assertTrue(\"Second Element not destroyed\", e2Tracker.waitDestroyed());\n        \n    }\n    @Test\n    public void testBinRetrieval() throws Exception {\n        Bin bin = new Bin(\"test\");\n        Element e1 = ElementFactory.make(\"fakesrc\", \"source\");\n        Element e2 = ElementFactory.make(\"fakesink\", \"sink\");\n        bin.addMany(e1, e2);\n        int id1 = System.identityHashCode(e1);\n        int id2 = System.identityHashCode(e2);\n        \n        e1 = null;\n        e2 = null;\n        System.gc();\n        Thread.sleep(10);\n        // Should return the same object that was put into the bin\n        assertEquals(\"source ID does not match\", id1, System.identityHashCode(bin.getElementByName(\"source\")));\n        assertEquals(\"sink ID does not match\", id2, System.identityHashCode(bin.getElementByName(\"sink\")));       \n    }\n    @Test\n    public void pipeline() {\n        Pipeline pipe = new Pipeline(\"test\");\n        GCTracker pipeTracker = new GCTracker(pipe);\n        pipe = null;\n        assertTrue(\"Pipe not garbage collected\", pipeTracker.waitGC());\n        System.out.println(\"checking if pipeline is destroyed\");\n        assertTrue(\"Pipe not destroyed\", pipeTracker.waitDestroyed());\n    }\n    @Test\n    public void pipelineBus() {\n        Pipeline pipe = new Pipeline(\"test\");\n        Bus bus = pipe.getBus();\n        GCTracker busTracker = new GCTracker(bus);\n        GCTracker pipeTracker = new GCTracker(pipe);\n        \n        pipe = null;\n        bus = null;\n        assertTrue(\"Bus not garbage collected\", busTracker.waitGC());\n        assertTrue(\"Bus not destroyed\", busTracker.waitDestroyed());\n        assertTrue(\"Pipe not garbage collected\", pipeTracker.waitGC());\n        assertTrue(\"Pipe not destroyed\", pipeTracker.waitDestroyed());\n\n    }\n    @Test\n    public void busWithListeners() {\n        Pipeline pipe = new Pipeline(\"test\");\n        Bus bus = pipe.getBus();\n        bus.connect(new Bus.EOS() {\n\n            public void endOfStream(GstObject source) {\n            }\n        });\n        \n        GCTracker busTracker = new GCTracker(bus);\n        GCTracker pipeTracker = new GCTracker(pipe);\n        bus = null;\n        pipe = null;\n        assertTrue(\"Bus not garbage collected\", busTracker.waitGC());\n        assertTrue(\"Bus not destroyed\", busTracker.waitDestroyed());\n        assertTrue(\"Pipe not garbage collected\", pipeTracker.waitGC());\n        assertTrue(\"Pipe not destroyed\", pipeTracker.waitDestroyed());\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/GhostPadTest.java",
    "content": "/* \n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\n/**\n *\n * @author wayne\n */\npublic class GhostPadTest {\n\n    public GhostPadTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(\"GhostPadTest\", new String[] {});\n    }\n    \n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n\n    @Before\n    public void setUp() {\n    }\n\n    @After\n    public void tearDown() {\n    }\n\n    // TODO add test methods here.\n    // The methods must be annotated with annotation @Test. For example:\n    //\n    // @Test\n    // public void hello() {}\n    @Test\n    public void newGhostPad() {\n        Element fakesink = ElementFactory.make(\"fakesink\", \"fs\");\n        @SuppressWarnings(\"unused\")\n        GhostPad gpad = new GhostPad(\"ghostsink\", fakesink.getStaticPad(\"sink\"));\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/GobjectSubclassTest.java",
    "content": "/* \n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.lowlevel.BaseSrcAPI;\nimport org.freedesktop.gstreamer.lowlevel.GObjectAPI;\nimport org.freedesktop.gstreamer.lowlevel.GType;\nimport org.freedesktop.gstreamer.lowlevel.GObjectAPI.GClassInitFunc;\nimport org.freedesktop.gstreamer.lowlevel.GObjectAPI.GInstanceInitFunc;\nimport org.freedesktop.gstreamer.lowlevel.GObjectAPI.GTypeInstance;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\nimport com.sun.jna.Pointer;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.freedesktop.gstreamer.lowlevel.GObjectAPI.GOBJECT_API;\nimport static org.freedesktop.gstreamer.lowlevel.GstPadTemplateAPI.GSTPADTEMPLATE_API;\n\n/**\n *\n * @author wayne\n */\npublic class GobjectSubclassTest {\n\n    public GobjectSubclassTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n//        GObjectAPI.gobj.g_type_init_with_debug_flags(1 << 0);\n        Gst.init(\"test\", new String[] {});\n    }\n    \n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n\n    @Before\n    public void setUp() throws Exception {\n    }\n\n    @After\n    public void tearDown() throws Exception {\n    }\n    @Test \n    public void registerNewGObjectClass() throws Exception {\n        final PadTemplate template = new PadTemplate(\"src\", PadDirection.SRC, \n                Caps.anyCaps());\n        final boolean[] classInitCalled  = { false };\n        final GClassInitFunc classInit = new GClassInitFunc() {\n\n            public void callback(Pointer g_class, Pointer class_data) {\n                classInitCalled[0] = true;\n            }\n        };\n        final GObjectAPI.GBaseInitFunc baseInit = new GObjectAPI.GBaseInitFunc() {\n\n            public void callback(Pointer g_class) {\n                GSTPADTEMPLATE_API.gst_element_class_add_pad_template(g_class, template);                    \n            }\n        };\n        final boolean[] instanceInitCalled  = { false };\n        final GInstanceInitFunc instanceInit = new GInstanceInitFunc() {\n\n            public void callback(GTypeInstance instance, Pointer g_class) {\n                instanceInitCalled[0] = true;                \n            }\n        };\n        final String name = \"NewTestClass\";\n\n        GObjectAPI.GTypeInfo info = new GObjectAPI.GTypeInfo();\n        info.clear();\n        info.class_init = classInit;\n        info.instance_init = instanceInit;\n        info.class_size = (short)new BaseSrcAPI.GstBaseSrcClass().size();\n        info.instance_size = (short)new BaseSrcAPI.GstBaseSrcStruct().size();\n        info.class_size = 1024;\n        info.base_init = baseInit;\n        info.instance_size = 1024;        \n        \n        GType type = GOBJECT_API.g_type_register_static(BaseSrcAPI.BASESRC_API.gst_base_src_get_type(), \n                name, info, 0);\n        System.out.println(\"New type=\" + type);\n        assertEquals(\"Name incorrect\", name, GOBJECT_API.g_type_name(type));\n        assertEquals(\"Cannot locate type by name\", type, GOBJECT_API.g_type_from_name(name));\n        \n        //Pointer instance = GOBJECT_API.g_type_create_instance(type);\n        GOBJECT_API.g_object_new(type, new Object[0]);\n        \n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/GstTypesTest.java",
    "content": "/* \n * Copyright (c) 2016 Christophe Lafolet\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GObjectPtr;\nimport static org.junit.Assert.assertEquals;\n\nimport org.freedesktop.gstreamer.lowlevel.GType;\nimport org.freedesktop.gstreamer.lowlevel.GstTypes;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\npublic class GstTypesTest {\n\n    public GstTypesTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(\"GstTypesTest\", new String[] {});\n    }\n    \n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n\n    @Before\n    public void setUp() {\n    }\n\n    @After\n    public void tearDown() {\n    }\n\n    @Test \n    public void registeredClassTest() {\n    \t// check a registered class\n    \tGType elementType = GType.valueOf(Element.GTYPE_NAME);\n    \tassertEquals(Element.class, GstTypes.classFor(elementType));\n    \tassertEquals(elementType, GstTypes.typeFor(Element.class));\n    }\n\n    @Test \n    public void unregisteredClassTest() {\n    \tGType elementType = GType.valueOf(Element.GTYPE_NAME);\n    \t// check a unregistered class which derived from Element \n    \tElement anElement = ElementFactory.make(\"avidemux\", \"avidemux\");\n//    \tassertEquals(Element.class, GstTypes.classFor(anElement.getType()));\n    \tassertEquals(Element.class, GstTypes.classFor(\n                Natives.getPointer(anElement)\n                        .as(GObjectPtr.class, GObjectPtr::new).getGType()));\n    \t\n    \t// verify GType has not changed for Element.class\n    \tassertEquals(elementType, GstTypes.typeFor(Element.class));\n    }\n}\n\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/InitTest.java",
    "content": "/* \n * Copyright (c) 2025 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport static org.junit.Assert.assertTrue;\n\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\n/**\n *\n */\npublic class InitTest {\n    \n    public InitTest() {\n        \n    }\n    @Test\n    public void testInit() {\n        Version available = Gst.getVersion();\n        Version notAvailable = Version.of(available.getMajor(), available.getMinor() + 2);\n        try {\n            Gst.init(notAvailable);\n            assertTrue(\"Version check exception not thrown!\", false);\n        } catch (GstException ex) {\n            System.out.println(\"Expected init failure\");\n            System.out.println(ex);\n        }\n        String[] args = Gst.init(available, \"InitTest\", \"--gst-debug-no-color\");\n        assertTrue(args.length == 0);\n        \n        assertTrue(Gst.testVersion(available.getMajor(), available.getMinor()));\n        assertTrue(Gst.testVersion(available.getMajor(), available.getMinor() - 2));\n        assertTrue(!Gst.testVersion(notAvailable.getMajor(), notAvailable.getMinor()));\n        \n        Gst.deinit();\n    }\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n    }\n\n    @AfterClass\n    public static void tearDownClass() throws Exception {\n    }\n\n    @Before\n    public void setUp() throws Exception {\n    }\n\n    @After\n    public void tearDown() throws Exception {\n    }\n    \n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/MessageTest.java",
    "content": "/* \n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.concurrent.atomic.AtomicReference;\nimport org.freedesktop.gstreamer.message.BufferingMessage;\nimport org.freedesktop.gstreamer.message.DurationChangedMessage;\nimport org.freedesktop.gstreamer.message.EOSMessage;\nimport org.freedesktop.gstreamer.message.LatencyMessage;\nimport org.freedesktop.gstreamer.message.Message;\nimport org.freedesktop.gstreamer.message.MessageType;\nimport org.freedesktop.gstreamer.message.SegmentDoneMessage;\nimport org.freedesktop.gstreamer.message.StateChangedMessage;\nimport org.freedesktop.gstreamer.message.TagMessage;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\nimport static org.freedesktop.gstreamer.lowlevel.GstElementAPI.GSTELEMENT_API;\nimport static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API;\nimport static org.freedesktop.gstreamer.lowlevel.GstTagListAPI.GSTTAGLIST_API;\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertNotNull;\nimport static org.junit.Assert.assertTrue;\n\n/**\n *\n */\npublic class MessageTest {\n\n    public MessageTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(\"MessageTest\");\n    }\n\n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n\n    @Before\n    public void setUp() {\n    }\n\n    @After\n    public void tearDown() {\n    }\n\n    @Test\n    public void gst_message_new_eos() {\n        Element fakesink = ElementFactory.make(\"fakesink\", \"sink\");\n        Message msg = GSTMESSAGE_API.gst_message_new_eos(fakesink);\n        assertTrue(\"gst_message_new_eos did not return an instance of EOSMessage\", msg instanceof EOSMessage);\n    }\n\n    @Test\n    public void EOSMessage_getSource() {\n        Element fakesink = ElementFactory.make(\"fakesink\", \"sink\");\n        Message msg = GSTMESSAGE_API.gst_message_new_eos(fakesink);\n        assertEquals(\"Wrong source in message\", fakesink, msg.getSource());\n    }\n\n    @Test\n    public void postEOS() {\n        final TestPipe pipe = new TestPipe();\n        final AtomicBoolean signalFired = new AtomicBoolean(false);\n        final AtomicReference<Message> signalMessage = new AtomicReference<>(null);\n        pipe.getBus().connect(\"message::eos\", new Bus.MESSAGE() {\n\n            @Override\n            public void busMessage(Bus bus, Message msg) {\n                signalFired.set(true);\n                signalMessage.set(msg);\n                pipe.quit();\n            }\n        });\n        pipe.play();\n        GSTELEMENT_API.gst_element_post_message(pipe.sink, new EOSMessage(pipe.sink));\n        pipe.run();\n\n        Message msg = signalMessage.get();\n        assertNotNull(\"No message available on bus\", msg);\n        assertEquals(\"Wrong message type\", MessageType.EOS, msg.getType());\n        assertTrue(\"Message not intance of EOSMessage\", msg instanceof EOSMessage);\n        assertEquals(\"Wrong source in message\", pipe.pipe, msg.getSource());\n        pipe.dispose();\n    }\n\n    @Test\n    public void gst_message_new_percent() {\n        Element fakesink = ElementFactory.make(\"fakesink\", \"sink\");\n        Message msg = GSTMESSAGE_API.gst_message_new_buffering(fakesink, 55);\n        assertTrue(\"gst_message_new_eos did not return an instance of BufferingMessage\", msg instanceof BufferingMessage);\n    }\n\n    @Test\n    public void BufferingMessage_getPercent() {\n        Element fakesink = ElementFactory.make(\"fakesink\", \"sink\");\n        BufferingMessage msg = (BufferingMessage) GSTMESSAGE_API.gst_message_new_buffering(fakesink, 55);\n        assertEquals(\"Wrong source in message\", 55, msg.getPercent());\n    }\n\n    @Test\n    public void postBufferingMessage() {\n        final TestPipe pipe = new TestPipe();\n        final AtomicBoolean signalFired = new AtomicBoolean(false);\n        final AtomicReference<Message> signalMessage = new AtomicReference<>(null);\n        pipe.getBus().connect(\"message::buffering\", new Bus.MESSAGE() {\n\n            public void busMessage(Bus bus, Message msg) {\n                signalFired.set(true);\n                signalMessage.set(msg);\n                pipe.quit();\n            }\n        });\n        final int PERCENT = 55;\n        GSTELEMENT_API.gst_element_post_message(pipe.sink, new BufferingMessage(pipe.src, PERCENT));\n        pipe.run();\n        Message msg = signalMessage.get();\n        assertNotNull(\"No message available on bus\", msg);\n        assertEquals(\"Wrong message type\", MessageType.BUFFERING, msg.getType());\n        assertTrue(\"Message not instance of BufferingMessage\", msg instanceof BufferingMessage);\n        assertEquals(\"Wrong source in message\", pipe.src, msg.getSource());\n        assertEquals(\"Wrong percent value in message\", PERCENT, ((BufferingMessage) msg).getPercent());\n        pipe.dispose();\n    }\n\n    @Test\n    public void gst_message_new_duration() {\n        Element fakesink = ElementFactory.make(\"fakesink\", \"sink\");\n        Message msg = GSTMESSAGE_API.gst_message_new_duration_changed(fakesink);\n        assertTrue(\"gst_message_new_duration did not return an instance of DurationMessage\", msg instanceof DurationChangedMessage);\n    }\n\n    @Test\n    public void postDurationMessage() {\n        final TestPipe pipe = new TestPipe();\n        final AtomicBoolean signalFired = new AtomicBoolean(false);\n        final AtomicReference<Message> signalMessage = new AtomicReference<>(null);\n        pipe.getBus().connect(\"message::duration-changed\", new Bus.MESSAGE() {\n\n            @Override\n            public void busMessage(Bus bus, Message msg) {\n                signalFired.set(true);\n                signalMessage.set(msg);\n                pipe.quit();\n            }\n        });\n        GSTELEMENT_API.gst_element_post_message(pipe.src, new DurationChangedMessage(pipe.src));\n        pipe.play().run();\n        Message msg = signalMessage.get();\n        assertNotNull(\"No message available on bus\", msg);\n        assertEquals(\"Wrong message type\", MessageType.DURATION_CHANGED, msg.getType());\n        assertTrue(\"Message not instance of EOSMessage\", msg instanceof DurationChangedMessage);\n        assertEquals(\"Wrong source in message\", pipe.src, msg.getSource());\n        pipe.dispose();\n    }\n\n    @Test\n    public void gst_message_new_tag() {\n        Element src = ElementFactory.make(\"fakesrc\", \"src\");\n        Message msg = GSTMESSAGE_API.gst_message_new_tag(src, new TagList());\n        assertTrue(\"gst_message_new_tag did not return an instance of TagMessage\", msg instanceof TagMessage);\n    }\n\n    @Test\n    public void TagMessage_getTagList() {\n        Element src = ElementFactory.make(\"fakesrc\", \"src\");\n        TagList tl = new TagList();\n        final String MAGIC = \"fubar\";\n        GSTTAGLIST_API.gst_tag_list_add(tl, TagMergeMode.APPEND, \"artist\", MAGIC);\n        TagMessage msg = (TagMessage) GSTMESSAGE_API.gst_message_new_tag(src, tl);\n        tl = msg.getTagList();\n        assertEquals(\"Wrong artist in tag list\", MAGIC, tl.getString(\"artist\", 0));\n    }\n\n    @Test\n    public void gst_message_new_state_changed() {\n        Element src = ElementFactory.make(\"fakesrc\", \"src\");\n        Message msg = GSTMESSAGE_API.gst_message_new_state_changed(src, State.READY, State.PLAYING, State.VOID_PENDING);\n        assertTrue(\"gst_message_new_state_changed did not return an instance of StateChangedMessage\", msg instanceof StateChangedMessage);\n    }\n\n    @Test\n    public void constructStateChanged() {\n        Element src = ElementFactory.make(\"fakesrc\", \"src\");\n        new StateChangedMessage(src, State.READY, State.PLAYING, State.VOID_PENDING);\n    }\n\n    @Test\n    public void StateChanged_get() {\n        Element src = ElementFactory.make(\"fakesrc\", \"src\");\n        StateChangedMessage msg = (StateChangedMessage) GSTMESSAGE_API.gst_message_new_state_changed(src, State.READY, State.PLAYING, State.VOID_PENDING);\n        assertEquals(\"Wrong old state\", State.READY, msg.getOldState());\n        assertEquals(\"Wrong new state\", State.PLAYING, msg.getNewState());\n        assertEquals(\"Wrong pending state\", State.VOID_PENDING, msg.getPendingState());\n    }\n\n    @Test\n    public void postStateChangedMessage() {\n        final TestPipe pipe = new TestPipe();\n        final AtomicBoolean signalFired = new AtomicBoolean(false);\n        final AtomicReference<Message> signalMessage = new AtomicReference<Message>(null);\n\n        pipe.getBus().connect(\"message::state-changed\", new Bus.MESSAGE() {\n\n            public void busMessage(Bus bus, Message msg) {\n                signalFired.set(true);\n                signalMessage.set(msg);\n                pipe.quit();\n            }\n        });\n        GSTELEMENT_API.gst_element_post_message(pipe.src,\n                new StateChangedMessage(pipe.src, State.READY, State.PLAYING, State.VOID_PENDING));\n        pipe.run();\n        Message msg = signalMessage.get();\n        assertNotNull(\"No message available on bus\", msg);\n        assertEquals(\"Wrong message type\", MessageType.STATE_CHANGED, msg.getType());\n        StateChangedMessage smsg = (StateChangedMessage) msg;\n        assertEquals(\"Wrong old state\", State.READY, smsg.getOldState());\n        assertEquals(\"Wrong new state\", State.PLAYING, smsg.getNewState());\n        assertEquals(\"Wrong pending state\", State.VOID_PENDING, smsg.getPendingState());\n        pipe.dispose();\n    }\n\n    @Test\n    public void gst_message_new_segment_done() {\n        Element src = ElementFactory.make(\"fakesrc\", \"src\");\n        Message msg = GSTMESSAGE_API.gst_message_new_segment_done(src, Format.TIME, 0xdeadbeef);\n        assertTrue(\"gst_message_new_segment_done did not return an instance of SegmentDoneMessage\",\n                msg instanceof SegmentDoneMessage);\n    }\n\n    @Test\n    public void constructSegmentDone() {\n        Element src = ElementFactory.make(\"fakesrc\", \"src\");\n        new SegmentDoneMessage(src, Format.TIME, 0xdeadbeef);\n    }\n\n    @Test\n    public void parseSegmentDone() {\n        Element src = ElementFactory.make(\"fakesrc\", \"src\");\n        SegmentDoneMessage msg = (SegmentDoneMessage) GSTMESSAGE_API.gst_message_new_segment_done(src, Format.TIME, 0xdeadbeef);\n        assertEquals(\"Wrong format\", Format.TIME, msg.getFormat());\n        assertEquals(\"Wrong position\", 0xdeadbeef, msg.getPosition());\n    }\n\n    @Test\n    public void postSegmentDoneMessage() {\n        final TestPipe pipe = new TestPipe();\n        final AtomicBoolean signalFired = new AtomicBoolean(false);\n        final AtomicReference<Message> signalMessage = new AtomicReference<>(null);\n\n        pipe.getBus().connect(\"message::segment-done\", new Bus.MESSAGE() {\n\n            public void busMessage(Bus bus, Message msg) {\n                signalFired.set(true);\n                signalMessage.set(msg);\n                pipe.quit();\n            }\n        });\n        final int POSITION = 0xdeadbeef;\n        GSTELEMENT_API.gst_element_post_message(pipe.src,\n                new SegmentDoneMessage(pipe.src, Format.TIME, POSITION));\n        pipe.run();\n        Message msg = signalMessage.get();\n        assertNotNull(\"No message available on bus\", msg);\n        assertEquals(\"Wrong message type\", MessageType.SEGMENT_DONE, msg.getType());\n        SegmentDoneMessage smsg = (SegmentDoneMessage) msg;\n        assertEquals(\"Wrong format\", Format.TIME, smsg.getFormat());\n        assertEquals(\"Wrong position\", POSITION, smsg.getPosition());\n        pipe.dispose();\n    }\n\n    @Test\n    public void postLatencyMessage() {\n        final TestPipe pipe = new TestPipe();\n        final AtomicBoolean signalFired = new AtomicBoolean(false);\n        final AtomicReference<Message> signalMessage = new AtomicReference<>(null);\n\n        pipe.getBus().connect(\"message::latency\", new Bus.MESSAGE() {\n\n            @Override\n            public void busMessage(Bus bus, Message msg) {\n                signalFired.set(true);\n                signalMessage.set(msg);\n                pipe.quit();\n            }\n        });\n        GSTELEMENT_API.gst_element_post_message(pipe.src,\n                new LatencyMessage(pipe.src));\n        pipe.run();\n        Message msg = signalMessage.get();\n        assertNotNull(\"No message available on bus\", msg);\n        assertEquals(\"Wrong message type\", MessageType.LATENCY, msg.getType());\n        @SuppressWarnings(\"unused\")\n        LatencyMessage smsg = (LatencyMessage) msg;\n        pipe.dispose();\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/PadProbeTypeTest.java",
    "content": "/* \n * Copyright (c) 2020 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport java.lang.reflect.Field;\nimport java.util.Set;\nimport org.freedesktop.gstreamer.glib.NativeFlags;\nimport org.freedesktop.gstreamer.lowlevel.GstPadAPI;\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\npublic class PadProbeTypeTest {\n    \n\n    @Test\n    public void testCombinations() throws Exception {\n        for (Field field : PadProbeType.class.getFields()) {\n            if (Set.class.isAssignableFrom(field.getType())) {\n                Set<PadProbeType> flags = (Set<PadProbeType>) field.get(null);\n//                System.out.println(field.getName() + \" : \" + flags);\n                Field nativeField = GstPadAPI.class.getField(\"GST_PAD_PROBE_TYPE_\" + field.getName());\n                assertEquals(NativeFlags.toInt(flags), nativeField.get(null));\n            }\n        }\n    }\n    \n    \n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/PadTemplateTest.java",
    "content": "/* \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport static org.junit.Assert.assertEquals;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\n/**\n *\n * @author inx\n */\npublic class PadTemplateTest {\n    \n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(\"test\", new String[] {});\n    }\n    \n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n    \n    @Before\n    public void setUp() throws Exception {\n    }\n    \n    @After\n    public void tearDown() throws Exception {\n    }\n    \n    @Test\n    public void padTemplate()\n        throws Exception\n    {\n        Element src = ElementFactory.make(\"fakesrc\", \"src\");\n        Element sink = ElementFactory.make(\"fakesink\", \"sink\");        \n        Pad srcPad = src.getStaticPad(\"src\");\n        Pad sinkPad = sink.getStaticPad(\"sink\");        \n        PadTemplate template;\n        \n        template = srcPad.getTemplate();        \n        assertEquals(\"wrong name!\", template.getTemplateName(), \"src\");\n        assertEquals(\"wrong direction!\", template.getDirection(), PadDirection.SRC);\n        assertEquals(\"wrong presence!\", template.getPresence(), PadPresence.ALWAYS);        \n        \n        template = sinkPad.getTemplate();\n        assertEquals(\"wrong name!\", template.getTemplateName(), \"sink\");\n        assertEquals(\"wrong direction!\", template.getDirection(), PadDirection.SINK);\n        assertEquals(\"wrong presence!\", template.getPresence(), PadPresence.ALWAYS);\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/PadTest.java",
    "content": "/* \n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.event.Event;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertNotNull;\nimport static org.junit.Assert.assertNotSame;\nimport static org.junit.Assert.assertTrue;\n\nimport java.lang.ref.WeakReference;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.concurrent.atomic.AtomicReference;\nimport org.freedesktop.gstreamer.event.FlushStopEvent;\n\nimport org.freedesktop.gstreamer.event.TagEvent;\nimport org.freedesktop.gstreamer.query.AllocationQuery;\nimport org.freedesktop.gstreamer.query.Query;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\n/**\n *\n */\npublic class PadTest {\n\n    public PadTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(\"test\", new String[]{});\n    }\n\n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n\n    @Before\n    public void setUp() throws Exception {\n    }\n\n    @After\n    public void tearDown() throws Exception {\n    }\n\n    @Test\n    public void getPad() throws Exception {\n        Element src = ElementFactory.make(\"fakesrc\", \"src\");\n        Element sink = ElementFactory.make(\"fakesink\", \"sink\");\n        Pad srcPad = src.getStaticPad(\"src\");\n        Pad sinkPad = sink.getStaticPad(\"sink\");\n        assertNotNull(\"Could not get src pad\", srcPad);\n        assertNotNull(\"Could not get sink pad\", sinkPad);\n        src = null;\n        sink = null;\n        WeakReference<Pad> srcRef = new WeakReference<>(srcPad);\n        WeakReference<Pad> sinkRef = new WeakReference<>(sinkPad);\n        srcPad = null;\n        sinkPad = null;\n        assertTrue(\"Src pad not garbage collected\", GCTracker.waitGC(srcRef));\n        assertTrue(\"Sink pad not garbage collected\", GCTracker.waitGC(sinkRef));\n    }\n\n    @Test\n    public void padLink() throws Exception {\n        Element src = ElementFactory.make(\"fakesrc\", \"src\");\n        Element sink = ElementFactory.make(\"fakesink\", \"src\");\n        Pad srcPad = src.getStaticPad(\"src\");\n        Pad sinkPad = sink.getStaticPad(\"sink\");\n        srcPad.link(sinkPad);\n    }\n\n    @Test\n    public void addEventProbe() {\n        Element elem = ElementFactory.make(\"identity\", \"src\");\n        Event ev = new TagEvent(new TagList());\n\n        Pad sink = elem.getStaticPad(\"sink\");\n\n        final AtomicReference<Event> e = new AtomicReference<Event>();\n\n        Pad.EVENT_PROBE event_probe = new Pad.EVENT_PROBE() {\n\n            public PadProbeReturn eventReceived(Pad pad, Event event) {\n                e.set(event);\n                return PadProbeReturn.OK;\n            }\n        };\n\n        sink.setActive(true);\n        sink.sendEvent(new FlushStopEvent());\n\n        sink.addEventProbe(event_probe);\n        sink.sendEvent(ev);\n        assertEquals(\"event_prober.probeEvent() was not called\", ev, e.get());\n\n        sink.removeEventProbe(event_probe);\n\n        Event ev2 = new TagEvent(new TagList());\n        sink.sendEvent(ev2);\n        assertNotSame(\"event_prober.probeEvent() should not have been called\", ev2, e.get());\n    }\n    \n    @Test\n    public void addEventProbe_Remove() {\n        Element elem = ElementFactory.make(\"identity\", \"src\");\n        Event ev = new TagEvent(new TagList());\n\n        Pad sink = elem.getStaticPad(\"sink\");\n\n        final AtomicReference<Event> e = new AtomicReference<Event>();\n\n        Pad.EVENT_PROBE event_probe = new Pad.EVENT_PROBE() {\n\n            public PadProbeReturn eventReceived(Pad pad, Event event) {\n                e.set(event);\n                return PadProbeReturn.REMOVE;\n            }\n        };\n\n        sink.setActive(true);\n        sink.sendEvent(new FlushStopEvent());\n\n        sink.addEventProbe(event_probe);\n        sink.sendEvent(ev);\n        assertEquals(\"event_prober.probeEvent() was not called\", ev, e.get());\n\n        Event ev2 = new TagEvent(new TagList());\n        sink.sendEvent(ev2);\n        assertNotSame(\"event_prober.probeEvent() should not have been called\", ev2, e.get());\n        \n        WeakReference<Pad.EVENT_PROBE> probeRef = new WeakReference<>(event_probe);\n        event_probe = null;\n        assertTrue(\"Removed probe not collected\", GCTracker.waitGC(probeRef));\n        \n    }\n    \n    @Test\n    public void addProbe_Event() {\n        Element elem = ElementFactory.make(\"identity\", \"src\");\n        Event ev = new TagEvent(new TagList());\n\n        Pad sink = elem.getStaticPad(\"sink\");\n\n        final AtomicReference<Event> e = new AtomicReference<>();\n\n        Pad.PROBE probe = (Pad pad, PadProbeInfo info) -> {\n            assertTrue(\"Info type does not include event downstream\",\n                    info.getType().contains(PadProbeType.EVENT_DOWNSTREAM));\n            e.set(info.getEvent());\n            return PadProbeReturn.OK;\n        };\n\n        sink.setActive(true);\n        sink.sendEvent(new FlushStopEvent());\n\n        sink.addProbe(PadProbeType.EVENT_BOTH, probe);\n        sink.sendEvent(ev);\n        assertEquals(\"Probe (Event) was not called\", ev, e.get());\n\n        sink.removeProbe(probe);\n\n        Event ev2 = new TagEvent(new TagList());\n        sink.sendEvent(ev2);\n        assertNotSame(\"Probe (Event) should not have been called\", ev2, e.get());\n    }\n    \n    @Test\n    public void addProbe_EventRemove() {\n        Element elem = ElementFactory.make(\"identity\", \"src\");\n        Event ev = new TagEvent(new TagList());\n\n        Pad sink = elem.getStaticPad(\"sink\");\n\n        final AtomicReference<Event> e = new AtomicReference<>();\n\n        Pad.PROBE probe = (Pad pad, PadProbeInfo info) -> {\n            assertTrue(\"Info type does not include event downstream\",\n                    info.getType().contains(PadProbeType.EVENT_DOWNSTREAM));\n            e.set(info.getEvent());\n            return PadProbeReturn.REMOVE;\n        };\n\n        sink.setActive(true);\n        sink.sendEvent(new FlushStopEvent());\n\n        sink.addProbe(PadProbeType.EVENT_BOTH, probe);\n        sink.sendEvent(ev);\n        assertEquals(\"Probe (Event) was not called\", ev, e.get());\n\n        Event ev2 = new TagEvent(new TagList());\n        sink.sendEvent(ev2);\n        assertNotSame(\"Probe (Event) should not have been called\", ev2, e.get());\n        \n        WeakReference<Pad.PROBE> probeRef = new WeakReference<>(probe);\n        probe = null;\n        assertTrue(\"Removed probe not collected\", GCTracker.waitGC(probeRef));\n        \n        Event ev3 = new TagEvent(new TagList());\n        sink.sendEvent(ev3);\n        assertNotSame(\"Probe (Event) should not have been called\", ev3, e.get());\n    }\n\n    @Test\n    public void addDataProbe() {\n\n        Element elem = ElementFactory.make(\"identity\", \"src\");\n        Buffer buf = new Buffer(3);\n        Buffer buf2 = new Buffer(2);\n        final AtomicReference<Buffer> b = new AtomicReference<Buffer>();\n\n        Pad src = elem.getStaticPad(\"src\");\n\n        Pad.DATA_PROBE data_probe = new Pad.DATA_PROBE() {\n\n            @Override\n            public PadProbeReturn dataReceived(Pad pad, Buffer buffer) {\n                b.set(buffer);\n                return PadProbeReturn.OK;\n            }\n        };\n\n        elem.play();\n\n        // add a dataprobe\n        src.addDataProbe(data_probe);\n\n        // push data\n        FlowReturn res = src.push(buf);\n        assertEquals(\"data_prober.probeData() was not called\", buf, b.get());\n\n        // remove the dataprobe\n        src.removeDataProbe(data_probe);\n\n        // push data\n        res = src.push(buf2);\n        assertNotSame(\"data_prober.probeData() should not have been called\", buf2, b.get());\n\n        elem.stop();\n\n    }\n    \n    @Test\n    public void addProbe_Data() {\n\n        Element elem = ElementFactory.make(\"identity\", \"src\");\n        Buffer buf = new Buffer(3);\n        Buffer buf2 = new Buffer(2);\n        final AtomicReference<Buffer> b = new AtomicReference<>();\n\n        Pad src = elem.getStaticPad(\"src\");\n\n        Pad.PROBE probe = (Pad pad, PadProbeInfo info) -> {\n            assertTrue(\"Info type does not include buffer\",\n                    info.getType().contains(PadProbeType.BUFFER));\n            // These cause assertion messages to be logged by GStreamer\n            // assertTrue(info.getEvent() == null);\n            // assertTrue(info.getQuery() == null);\n            b.set(info.getBuffer());\n            return PadProbeReturn.OK;\n        };\n\n        elem.play();\n\n        // add a dataprobe\n        src.addProbe(PadProbeType.BUFFER, probe);\n\n        // push data\n        FlowReturn res = src.push(buf);\n        assertEquals(\"Probe (Data) was not called\", buf, b.get());\n\n        // remove the dataprobe\n        src.removeProbe(probe);\n\n        // push data\n        res = src.push(buf2);\n        assertNotSame(\"Probe (Data) should not have been called\", buf2, b.get());\n\n        elem.stop();\n\n    }\n    \n    @Test\n    public void addProbe_Idle() {\n\n        Element elem = ElementFactory.make(\"identity\", \"src\");\n        final AtomicBoolean called = new AtomicBoolean();\n\n        Pad src = elem.getStaticPad(\"src\");\n\n        Pad.PROBE probe = (Pad pad, PadProbeInfo info) -> {\n            called.set(true);\n            return PadProbeReturn.REMOVE;\n        };\n        \n        src.addProbe(PadProbeType.IDLE, probe);\n        \n        assertTrue(\"Idle probe not called\", called.get());\n        \n        WeakReference<Pad.PROBE> probeRef = new WeakReference<>(probe);\n        \n        probe = null;\n        \n        assertTrue(\"Idle probe not collected\", GCTracker.waitGC(probeRef));\n        \n    }\n    \n    @Test\n    public void addProbe_Query() {\n        ProbeTester.test(PadProbeType.QUERY_BOTH, info -> {\n            Query q = info.getQuery();\n            return q instanceof AllocationQuery;\n        });\n        \n    }\n    \n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/PipelineTest.java",
    "content": "/* \n * Copyright (c) 2018 Neil C Smith\n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.GError;\nimport org.freedesktop.gstreamer.glib.GObject;\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertNotNull;\nimport static org.junit.Assert.assertTrue;\n\nimport java.lang.ref.WeakReference;\nimport java.util.ArrayList;\nimport org.freedesktop.gstreamer.glib.Natives;\n\nimport org.freedesktop.gstreamer.lowlevel.GObjectAPI.GObjectStruct;\nimport org.freedesktop.gstreamer.lowlevel.GObjectPtr;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Ignore;\nimport org.junit.Test;\n\n/**\n *\n * @author wayne\n */\npublic class PipelineTest {\n    \n    public PipelineTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(\"PipelineTest\", new String[] {});\n    }\n    \n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n\n    @Before\n    public void setUp() throws Exception {\n    }\n\n    @After\n    public void tearDown() throws Exception {\n    }\n\n    public boolean waitRefCnt(GObjectStruct struct, int refcnt) throws InterruptedException {\n        System.gc();\n        struct.read();\n        for (int i = 0; struct.ref_count != refcnt && i < 20; ++i) {\n            Thread.sleep(10);\n            System.gc();\n            struct.read();\n        }\n        return struct.ref_count == refcnt;\n    }\n    \n    @Test\n    public void testPipelineGC() throws Exception {\n        Pipeline p = new Pipeline(\"test pipeline\");\n        int refcnt = new GObjectStruct((GObjectPtr) Natives.getPointer(p)).ref_count;\n        assertEquals(\"Refcount should be 1\", refcnt, 1);\n        WeakReference<GObject> pref = new WeakReference<GObject>(p);\n        p = null;\n        assertTrue(\"pipe not disposed\", GCTracker.waitGC(pref));\n    }\n    @Test\n    public void testBusGC() throws Exception {\n        Pipeline pipe = new Pipeline(\"test playbin\");\n        pipe.play();\n        Bus bus = pipe.getBus();\n        GObjectStruct struct = new GObjectStruct((GObjectPtr) Natives.getPointer(bus));\n        int refcnt = struct.ref_count;\n        assertTrue(refcnt > 1);\n        // reget the Bus - should return the same object and not increment ref count\n        Bus bus2 = pipe.getBus();\n        assertTrue(\"Did not get same Bus object\", bus == bus2);\n        struct.read(); // update struct fields\n        assertEquals(\"ref_count not equal\", refcnt, struct.ref_count);   \n        bus2 = null;\n        \n        WeakReference<Bus> bref = new WeakReference<Bus>(bus);\n        bus = null;      \n        // Since the pipeline holds a reference to the GstBus, the proxy should not be disposed\n        assertFalse(\"bus disposed prematurely\", GCTracker.waitGC(bref));\n        assertFalse(\"ref_count decremented prematurely\", waitRefCnt(struct, refcnt - 1));\n        \n        WeakReference<GObject> pref = new WeakReference<GObject>(pipe);\n        pipe.stop();\n        pipe = null;\n        assertTrue(\"pipe not disposed\", GCTracker.waitGC(pref));\n        struct.read();\n        System.out.println(\"bus ref_count=\" + struct.ref_count);\n        bus = null;\n        assertTrue(\"bus not disposed \" + struct.ref_count, GCTracker.waitGC(bref));\n        // This is a bit dangerous, since that memory could have been reused\n//        assertTrue(\"ref_count not decremented\", waitRefCnt(struct, 0));\n    } /* Test of getBus method, of class Pipeline. */\n    \n    \n    @Test\n    public void testParseLaunch() {\n        ArrayList<GError> errors = new ArrayList<GError>();\n        Pipeline pipeline = (Pipeline) Gst.parseLaunch(\"fakesrc ! fakesink\", errors);\n        assertNotNull(\"Pipeline not created\", pipeline);\n        assertEquals(\"parseLaunch with error!\", errors.size(), 0);\n    }\n    \n    @Test\n    public void testParseLaunchSingleElement() {\n        ArrayList<GError> errors = new ArrayList<GError>();\n        Element element = Gst.parseLaunch(\"fakesink\", errors);\n        assertNotNull(\"Element not created\", element);\n        assertFalse(\"Single element returned in Pipeline\", element instanceof Pipeline);\n        assertEquals(\"parseLaunch with error!\", errors.size(), 0);\n    }\n\n    @Test\n    public void testParseLaunchElementCount() {\n        ArrayList<GError> errors = new ArrayList<GError>();\n        Pipeline pipeline = (Pipeline) Gst.parseLaunch(\"fakesrc ! fakesink\", errors);\n        assertEquals(\"Number of elements in pipeline incorrect\", 2, pipeline.getElements().size());\n        assertEquals(\"parseLaunch with error!\", errors.size(), 0);\n    }\n    \n    @Test\n    public void testParseLaunchSrcElement() {\n        ArrayList<GError> errors = new ArrayList<GError>();\n        Pipeline pipeline = (Pipeline) Gst.parseLaunch(\"fakesrc ! fakesink\", errors);\n        assertEquals(\"First element not a fakesrc\", \"fakesrc\", pipeline.getSources().get(0).getFactory().getName());\n        assertEquals(\"parseLaunch with error!\", errors.size(), 0);\n    }\n    \n    @Test\n    public void testParseLaunchSinkElement() {\n        ArrayList<GError> errors = new ArrayList<GError>();\n        Pipeline pipeline = (Pipeline) Gst.parseLaunch(\"fakesrc ! fakesink\", errors);\n        assertEquals(\"First element not a fakesink\", \"fakesink\", pipeline.getSinks().get(0).getFactory().getName());\n        assertEquals(\"parseLaunch with error!\", errors.size(), 0);\n    }\n    \n    @Test\n    public void testParseLaunchStringArr() {\n        ArrayList<GError> errors = new ArrayList<GError>();\n        Pipeline pipeline = (Pipeline) Gst.parseLaunch(new String[] {\"fakesrc\", \"fakesink\"}, errors);\n        assertNotNull(\"Pipeline not created\", pipeline);\n        assertEquals(\"parseLaunch with error!\", errors.size(), 0);\n    } \n    \n    @Test\n    public void testParseLaunchStringArrElementCount() {\n        ArrayList<GError> errors = new ArrayList<GError>();\n        Pipeline pipeline = (Pipeline) Gst.parseLaunch(new String[] {\"fakesrc\", \"fakesink\"}, errors);\n        assertEquals(\"Number of elements in pipeline incorrect\", 2, pipeline.getElements().size());\n        assertEquals(\"parseLaunch with error!\", errors.size(), 0);\n    }\n    \n    @Test\n    public void testParseLaunchStringArrSrcElement() {\n        ArrayList<GError> errors = new ArrayList<GError>();\n        Pipeline pipeline = (Pipeline) Gst.parseLaunch(new String[] {\"fakesrc\", \"fakesink\"}, errors);\n        assertEquals(\"First element not a fakesrc\", \"fakesrc\", pipeline.getSources().get(0).getFactory().getName());\n        assertEquals(\"parseLaunch with error!\", errors.size(), 0);\n    }\n    \n    @Test\n    public void testParseLaunchStringArrSinkElement() {\n        ArrayList<GError> errors = new ArrayList<GError>();\n        Pipeline pipeline = (Pipeline) Gst.parseLaunch(new String[] {\"fakesrc\", \"fakesink\"}, errors);\n        assertEquals(\"First element not a fakesink\", \"fakesink\", pipeline.getSinks().get(0).getFactory().getName());\n        assertEquals(\"parseLaunch with error!\", errors.size(), 0);\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/PluginFeatureTest.java",
    "content": "/*\n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport org.junit.AfterClass;\nimport org.junit.Test;\nimport static org.junit.Assert.*;\nimport org.junit.BeforeClass;\n\npublic class PluginFeatureTest {\n    private static PluginFeature decodebinFeature;\n    \n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(\"PluginTest\", new String[] {});\n        decodebinFeature = Registry.get().lookupFeature(\"decodebin\");\n    }\n    \n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n\n    @Test\n    public void testToString() {\n        assertEquals(\"decodebin\", decodebinFeature.toString());\n    }\n\n    @Test\n    public void testGetName() {\n        assertEquals(\"decodebin\", decodebinFeature.getName());\n    }\n\n    @Test\n    public void testGetRank() {\n        assertEquals(0, decodebinFeature.getRank());\n    }\n\n    @Test\n    public void testCheckVersion() {\n        assertTrue(decodebinFeature.checkVersion(0, 0, 1));\n    }\n    \n    @Test\n    public void testGetPluginName() {\n        assertEquals(\"playback\", decodebinFeature.getPluginName());\n    }\n    \n    public void testGetPlugin() {\n        Plugin plugin = decodebinFeature.getPlugin();\n        assertNotNull(plugin);\n        assertEquals(\"playback\", plugin.getName());\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/PluginTest.java",
    "content": "/*\n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport org.junit.AfterClass;\nimport org.junit.Test;\nimport static org.junit.Assert.*;\nimport org.junit.BeforeClass;\n\n\npublic class PluginTest {\n    private static Plugin playbackPlugin;\n    \n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(\"PluginTest\", new String[] {});\n        playbackPlugin = Plugin.loadByName(\"playback\");\n    }\n    \n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n    \n    public PluginTest() {\n    }\n\n    @Test\n    public void testLoad_String() {\n        assertNotNull(playbackPlugin);\n    }\n\n    @Test\n    public void testGetName() {\n        assertTrue(playbackPlugin.getName().equals(\"playback\"));\n    }\n\n    @Test\n    public void testGetDescription() {\n        assertTrue(playbackPlugin.getDescription().equals(\"various playback elements\"));\n    }\n\n    @Test\n    public void testGetFilename() {\n        assertTrue(playbackPlugin.getFilename().contains(\"gstplayback\"));\n    }\n\n    @Test\n    public void testGetVersion() {\n        assertTrue(playbackPlugin.getVersion().matches(\"^(?:\\\\d+\\\\.)*\\\\d+$\"));\n    }\n\n    @Test\n    public void testGetLicense() {\n        assertTrue(playbackPlugin.getLicense().equals(\"LGPL\"));\n    }\n\n    @Test\n    public void testGetSource() {\n        assertTrue(playbackPlugin.getSource().equals(\"gst-plugins-base\"));\n    }\n\n    @Test\n    public void testGetPackage() {\n        String pkg = playbackPlugin.getPackage();\n        assertTrue(pkg.contains(\"GStreamer Base\")\n                   || pkg.contains(\"Gentoo GStreamer\"));\n    }\n\n    @Test\n    public void testGetOrigin() {\n        assertTrue(playbackPlugin.getOrigin().length() > 0);\n    }\n    \n    @Test\n    public void testGetReleaseDateString() {\n        assertTrue(playbackPlugin.getReleaseDateString().matches(\".*\\\\d{4}-\\\\d{2}-\\\\d{2}.*\"));\n    }\n    \n    public void testIsLoaded() {\n        assertTrue(playbackPlugin.isLoaded());\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/ProbeTester.java",
    "content": "/*\n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2020 John Cortell\n *\n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport java.util.Set;\n\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertNotNull;\nimport static org.junit.Assert.fail;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.TimeoutException;\nimport java.util.function.Predicate;\n\n/**\n * Utility class for unit testing API that operates on a Probe.\n * <p>\n * Call {@link ProbeTester#test(Consumer)} and pass a callback which will\n * perform the test on a PadProbeInfo it is supplied. The callback runs in a Pad\n * probe. The test uses a simple, ephemeral pipeline that is fed by a video test\n * source (or custom pipeline).\n * <p>\n * The callback is a {@link Predicate} and should return false if the input info\n * doesn't match that required by the test. Test exceptions should be thrown as\n * normal. This is to allow the probe to be called repeatedly until the input\n * info matches that expected. If the probe never matches the test will time\n * out.\n */\npublic class ProbeTester {\n\n    /**\n     * Run a probe test on a simple test pipeline. The callback will be called\n     * by the probe until it returns true, allowing for probe callbacks to be\n     * ignored. If the callback never returns true the test will timeout and\n     * fail.\n     * <p>\n     * The pipeline is <code>videotestsrc ! fakesink name=sink</code>. The probe\n     * will be attached to the sink pad of the sink element.\n     *\n     * @param mask PadProbeType mask to use when attaching probe to sink pad\n     * @param callback probe callback\n     */\n    public static void test(Set<PadProbeType> mask, Predicate<PadProbeInfo> callback) {\n        test(\"videotestsrc ! fakesink name=sink\", mask, callback);\n    }\n\n    /**\n     * Run a probe test on a simple test pipeline. The callback will be called\n     * by the probe until it returns true, allowing for probe callbacks to be\n     * ignored. If the callback never returns true the test will timeout and\n     * fail.\n     * <p>\n     * The pipeline must have a sink element named sink. The probe will be\n     * attached to the sink pad of the sink element.\n     *\n     * @param pipeline custom pipeline with named sink element\n     * @param mask PadProbeType mask to use when attaching probe to sink pad\n     * @param callback probe callback\n     */\n    public static void test(String pipeline, Set<PadProbeType> mask, Predicate<PadProbeInfo> callback) {\n        assertNotNull(\"Pipeline description can not be null\", pipeline);\n        assertFalse(\"Pipeline description can not be empty\", pipeline.isEmpty());\n        Pipeline pipe = (Pipeline) Gst.parseLaunch(pipeline);\n        assertNotNull(\"Unable to create Pipeline from pipeline description: \", pipe);\n\n        Element sink = pipe.getElementByName(\"sink\");\n        Pad pad = sink.getStaticPad(\"sink\");\n        PadProbe probe = new PadProbe(callback);\n        pad.addProbe(mask, probe);\n\n        pipe.play();\n\n        // Wait for the probe to complete\n        try {\n            probe.await(5000);\n        } catch (TimeoutException ex) {\n            fail(\"Timed out waiting for probe condition\\n\" + ex);\n        } catch (Exception ex) {\n            fail(\"Unexpected exception waiting for probe\\n\" + ex);\n        } finally {\n            pipe.stop();\n        }\n\n        // If the test threw an exception on the sample listener thread, throw it here\n        // (on the main thread)\n        if (probe.exception != null) {\n            throw new AssertionError(probe.exception);\n        }\n    }\n\n    private static class PadProbe implements Pad.PROBE {\n\n        private final CountDownLatch latch;\n        private final Predicate<PadProbeInfo> callback;\n\n        private Throwable exception;\n\n        PadProbe(Predicate<PadProbeInfo> callback) {\n            this.callback = callback;\n            latch = new CountDownLatch(1);\n        }\n\n        @Override\n        public PadProbeReturn probeCallback(Pad pad, PadProbeInfo info) {\n            if (latch.getCount() > 0) {\n                try {\n                    if (callback.test(info)) {\n                        latch.countDown();\n                    }\n                } catch (Throwable exc) {\n                    exception = exc;\n                    latch.countDown();\n                }\n            }\n            return PadProbeReturn.OK;\n        }\n\n        void await(long millis) throws InterruptedException, TimeoutException {\n            if (!latch.await(millis, TimeUnit.MILLISECONDS)) {\n                throw new TimeoutException();\n            }\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/PromiseTest.java",
    "content": "/* \n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2019 Kezhu Wang\n * Copyright (c) 2018 Antonio Morales\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertTrue;\n\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GPointer;\nimport org.freedesktop.gstreamer.lowlevel.GType;\nimport org.freedesktop.gstreamer.util.TestAssumptions;\nimport org.junit.BeforeClass;\nimport org.junit.AfterClass;\nimport org.junit.Test;\n\npublic class PromiseTest {\n\n    public PromiseTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(Gst.getVersion(), \"PromiseTest\");\n    }\n\n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n    \n    @Test\n    public void testReply() {\n        TestAssumptions.requireGstVersion(1, 14);\n        \n        Promise promise = new Promise();\n\n        promise.reply(null);\n\n        PromiseResult promiseStatus = promise.waitResult();\n\n        assertEquals(\"promise reply state not correct\", promiseStatus, PromiseResult.REPLIED);\n    }\n\n    @Test\n    public void testInterrupt() {\n        TestAssumptions.requireGstVersion(1, 14);\n        \n        Promise promise = new Promise();\n        promise.interrupt();\n\n        PromiseResult promiseStatus = promise.waitResult();\n\n        assertEquals(\"promise reply state not correct\", promiseStatus, PromiseResult.INTERRUPTED);\n    }\n\n    @Test\n    public void testExpire() {\n        TestAssumptions.requireGstVersion(1, 14);\n        \n        Promise promise = new Promise();\n        promise.expire();\n\n        PromiseResult promiseStatus = promise.waitResult();\n\n        assertEquals(\"promise reply state not correct\", promiseStatus, PromiseResult.EXPIRED);\n    }\n\n    @Test\n    public void testInvalidateReply() {\n        TestAssumptions.requireGstVersion(1, 14);\n        \n        Promise promise = new Promise();\n        Structure data = new Structure(\"data\");\n\n        assertTrue(Natives.ownsReference(data));\n        promise.reply(data);\n        assertFalse(Natives.ownsReference(data));\n        assertFalse(Natives.validReference(data));\n    }\n\n    @Test\n    public void testReplyData() {\n        TestAssumptions.requireGstVersion(1, 14);\n        \n        Promise promise = new Promise();\n        Structure data = new Structure(\"data\", \"test\", GType.UINT, 1);\n        GPointer pointer = Natives.getPointer(data);\n\n        promise.reply(data);\n        assertEquals(\"promise state not in replied\", promise.waitResult(), PromiseResult.REPLIED);\n\n        Structure result = promise.getReply();\n        assertEquals(\"result of promise does not match reply\", pointer, Natives.getPointer(result));\n    }\n\n    @Test\n    public void testDispose() {\n        TestAssumptions.requireGstVersion(1, 14);\n        \n        Promise promise = new Promise();\n        promise.interrupt();\n        promise.dispose();\n    }\n\n    @Test\n    public void testDisposeWithChangeFunc() {\n        TestAssumptions.requireGstVersion(1, 14);\n        \n        Promise promise = new Promise(new Promise.PROMISE_CHANGE() {\n            @Override\n            public void onChange(Promise promise) {\n            }\n        });\n        promise.interrupt();\n        promise.dispose();\n    }\n    \n    @Test\n    public void testChangeFunctionGC() {\n        TestAssumptions.requireGstVersion(1, 14);\n        \n        final AtomicBoolean onChangeFired = new AtomicBoolean(false);\n        \n        Promise promise = new Promise(new Promise.PROMISE_CHANGE() {\n            @Override\n            public void onChange(Promise promise) {\n                onChangeFired.set(true);\n            }\n        });\n        System.gc();\n        System.gc();\n        promise.interrupt();\n        assertTrue(\"Promise Change callback GC'd\", onChangeFired.get());\n        promise.dispose();\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/PropertyTypeTest.java",
    "content": "/* \n * Copyright (c) 2020 Peter Körner\n * Copyright (c) 2020 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.NativeEnum;\nimport org.freedesktop.gstreamer.util.TestAssumptions;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\npublic class PropertyTypeTest {\n\n    private Element audiotestsrc;\n    private Element filesink;\n    private Element convert;\n\n    @BeforeClass\n    public static void setUpClass() {\n        Gst.init(Gst.getVersion(), \"PropertyTypeTest\");\n    }\n\n    @AfterClass\n    public static void tearDownClass() {\n        Gst.deinit();\n    }\n\n    @Before\n    public void createElements() {\n        audiotestsrc = ElementFactory.make(\"audiotestsrc\", null);\n        filesink = ElementFactory.make(\"filesink\", null);\n        convert = ElementFactory.make(\"audioconvert\", null);\n    }\n\n    @After\n    public void disposeElements() {\n        audiotestsrc.dispose();\n        filesink.dispose();\n        convert.dispose();\n    }\n\n    @Test\n    public void setBool() {\n        audiotestsrc.set(\"do-timestamp\", true);\n        assertEquals(true, audiotestsrc.get(\"do-timestamp\"));\n\n        audiotestsrc.set(\"do-timestamp\", false);\n        assertEquals(false, audiotestsrc.get(\"do-timestamp\"));\n\n        audiotestsrc.setAsString(\"do-timestamp\", \"true\");\n        assertEquals(\"true\", audiotestsrc.getAsString(\"do-timestamp\"));\n    }\n\n    @Test\n    public void setDouble() {\n        audiotestsrc.set(\"freq\", 42.23);\n        assertEquals(42.23, audiotestsrc.get(\"freq\"));\n\n        audiotestsrc.set(\"freq\", 5_000_000.);\n        assertEquals(5_000_000., audiotestsrc.get(\"freq\"));\n\n        audiotestsrc.setAsString(\"freq\", \"42.23\");\n        assertEquals(42.23, audiotestsrc.get(\"freq\"));\n    }\n\n    @Test\n    public void setInt() {\n        audiotestsrc.set(\"num-buffers\", 0);\n        assertEquals(0, audiotestsrc.get(\"num-buffers\"));\n\n        audiotestsrc.set(\"num-buffers\", 42);\n        assertEquals(42, audiotestsrc.get(\"num-buffers\"));\n\n        audiotestsrc.set(\"num-buffers\", 2147483647);\n        assertEquals(2147483647, audiotestsrc.get(\"num-buffers\"));\n    }\n\n    @Test\n    public void setUInt() {\n        audiotestsrc.set(\"blocksize\", 0);\n        assertEquals(0, audiotestsrc.get(\"blocksize\"));\n\n        audiotestsrc.set(\"blocksize\", 42);\n        assertEquals(42, audiotestsrc.get(\"blocksize\"));\n\n        int maxUnsignedInt = Integer.parseUnsignedInt(\"4294967295\");\n        audiotestsrc.set(\"blocksize\", maxUnsignedInt);\n        assertEquals(maxUnsignedInt, audiotestsrc.get(\"blocksize\"));\n    }\n\n    @Test\n    public void setLong() {\n        audiotestsrc.set(\"timestamp-offset\", 0L);\n        assertEquals(0L, audiotestsrc.get(\"timestamp-offset\"));\n\n        audiotestsrc.set(\"timestamp-offset\", 42L);\n        assertEquals(42L, audiotestsrc.get(\"timestamp-offset\"));\n\n        audiotestsrc.set(\"timestamp-offset\", -42L);\n        assertEquals(-42L, audiotestsrc.get(\"timestamp-offset\"));\n\n        audiotestsrc.set(\"timestamp-offset\", 9223372036854775807L);\n        assertEquals(9223372036854775807L, audiotestsrc.get(\"timestamp-offset\"));\n\n        audiotestsrc.set(\"timestamp-offset\", -9223372036854775808L);\n        assertEquals(-9223372036854775808L, audiotestsrc.get(\"timestamp-offset\"));\n    }\n\n    @Test\n    public void setULong() {\n        filesink.set(\"max-bitrate\", 0L);\n        assertEquals(0L, filesink.get(\"max-bitrate\"));\n\n        long maxUnsignedLong = Long.parseUnsignedLong(\"18446744073709551615\");\n        filesink.set(\"max-bitrate\", maxUnsignedLong);\n        assertEquals(maxUnsignedLong, filesink.get(\"max-bitrate\"));\n\n        filesink.set(\"max-bitrate\", 42L);\n        assertEquals(42L, filesink.get(\"max-bitrate\"));\n\n        filesink.setAsString(\"max-bitrate\", \"18446744073709551615\");\n        assertEquals(maxUnsignedLong, filesink.get(\"max-bitrate\"));\n    }\n\n    @Test\n    public void setString() {\n        filesink.set(\"location\", \"\");\n        assertEquals(\"\", filesink.get(\"location\"));\n\n        filesink.set(\"location\", null);\n        assertNull(filesink.get(\"location\"));\n\n        filesink.set(\"location\", \"foobar\");\n        assertEquals(\"foobar\", filesink.get(\"location\"));\n    }\n\n    @Test\n    public void setEnum() {\n        audiotestsrc.set(\"wave\", 8);\n        assertEquals(8, audiotestsrc.get(\"wave\"));\n\n        audiotestsrc.setAsString(\"wave\", \"Silence\");\n        assertEquals(4, audiotestsrc.get(\"wave\"));\n        \n        // unfortunately returned strings do not seem to be consistent across\n        // different OS / builds - comment out pending a fix or removal\n        //        assertEquals(\"Silence\", audiotestsrc.getAsString(\"wave\"));\n\n        audiotestsrc.setAsString(\"wave\", \"square\");\n        assertEquals(1, audiotestsrc.get(\"wave\"));\n        //        assertEquals(\"Square\", audiotestsrc.getAsString(\"wave\"));\n\n        audiotestsrc.setAsString(\"wave\", \"red-noise\");\n        assertEquals(10, audiotestsrc.get(\"wave\"));\n        String redNoise = audiotestsrc.getAsString(\"wave\");\n        //        assertEquals(\"Red (brownian) noise\", redNoise);\n        audiotestsrc.setAsString(\"wave\", redNoise);\n        assertEquals(10, audiotestsrc.get(\"wave\"));\n\n        // invalid value\n        audiotestsrc.set(\"wave\", -256);\n        assertEquals(0, audiotestsrc.get(\"wave\"));\n        \n        // native enum\n        audiotestsrc.set(\"wave\", AudioTestSrcWave.SILENCE);\n        assertEquals(AudioTestSrcWave.SILENCE.intValue(), audiotestsrc.get(\"wave\"));\n        //        assertEquals(\"Silence\", audiotestsrc.getAsString(\"wave\"));\n        \n    }\n\n    @Test(expected = IllegalArgumentException.class)\n    public void setEnumInvalidString() {\n        audiotestsrc.setAsString(\"wave\", \"FOO\");\n    }\n\n    @Test\n    public void setValueArrayFromString() {\n        TestAssumptions.requireGstVersion(1, 14);\n\n        convert.setAsString(\"mix-matrix\", \"<<(float)0.25, (float)0.45>,<(float)0.65, (float)0.85>>\");\n        String mixMatrix = convert.getAsString(\"mix-matrix\");\n        assertTrue(mixMatrix.contains(\"0.2\"));\n        assertTrue(mixMatrix.contains(\"0.4\"));\n        assertTrue(mixMatrix.contains(\"0.6\"));\n        assertTrue(mixMatrix.contains(\"0.8\"));\n    }\n    \n     private static enum AudioTestSrcWave implements NativeEnum<AudioTestSrcWave>{\n        SINE(0),\n        SQUARE(1),\n        SAW(2),\n        TRIANGLE(3),\n        SILENCE(4),\n        WHITE_NOISE(5),\n        PINK_NOISE(6),\n        SINE_TABLE(7),\n        TICKS(8),\n        GAUSSIAN_NOISE(9),\n        RED_NOISE(10),\n        BLUE_NOISE(11),\n        VIOLET_NOISE(12);\n\n        private final int value;\n\n        private AudioTestSrcWave(int value) {\n            this.value = value;\n        }\n\n        @Override\n        public int intValue() {\n            return value;\n        }\n    }\n    \n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/QueryTest.java",
    "content": "/* \n * Copyright (c) 2009 Levente Farkas\n * Copyright (c) 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.query.Query;\nimport org.freedesktop.gstreamer.query.QueryType;\nimport static org.freedesktop.gstreamer.lowlevel.GstMiniObjectAPI.GSTMINIOBJECT_API;\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertNotNull;\nimport static org.junit.Assert.assertTrue;\n\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\nimport org.freedesktop.gstreamer.glib.Natives;\n\nimport org.freedesktop.gstreamer.lowlevel.GstQueryAPI;\nimport org.freedesktop.gstreamer.query.AllocationQuery;\nimport org.freedesktop.gstreamer.query.DurationQuery;\nimport org.freedesktop.gstreamer.query.FormatsQuery;\nimport org.freedesktop.gstreamer.query.LatencyQuery;\nimport org.freedesktop.gstreamer.query.PositionQuery;\nimport org.freedesktop.gstreamer.query.SeekingQuery;\nimport org.freedesktop.gstreamer.query.SegmentQuery;\nimport org.junit.AfterClass;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\n/**\n *\n * @author wayne\n */\npublic class QueryTest {\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(\"QueryTest\", new String[] {});\n    }\n    \n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n\n    @Test\n    public void gst_query_new_position() {\n        Query query = GstQueryAPI.GSTQUERY_API.gst_query_new_position(Format.TIME);\n        assertNotNull(\"Query.newPosition returned null\", query);\n        assertTrue(\"Returned query not instance of PositionQuery\", query instanceof PositionQuery);\n    }\n    @Test\n    public void getPositionQueryFormat() {\n        for (Format format : Format.values()) {\n            PositionQuery query = new PositionQuery(format);\n            assertEquals(\"Format returned from getFormat() is incorrect\" , format, query.getFormat());\n        }\n    }\n    @Test\n    public void getPosition() {\n        PositionQuery query = new PositionQuery(Format.TIME);\n        final long POSITION = 0xdeadbeef;\n        query.setPosition(Format.TIME, POSITION);\n        assertEquals(\"Incorrect position returned\", POSITION, query.getPosition());\n    }\n    @Test \n    public void positionQueryToString() {\n        PositionQuery query = new PositionQuery(Format.TIME);\n        query.setPosition(Format.TIME, 1234);\n        String s = query.toString();\n        assertTrue(\"toString() did not return format\", s.contains(\"format=TIME\"));\n        assertTrue(\"toString() did not return position\", s.contains(\"position=1234\"));\n    }\n    @Test\n    public void newDurationQuery() {\n        Query query = new DurationQuery(Format.TIME);\n        assertNotNull(\"Query.newDuration returned null\", query);\n        assertTrue(\"Returned query not instance of DurationQuery\", query instanceof DurationQuery);\n    }\n    @Test\n    public void gst_query_new_duration() {\n        Query query = GstQueryAPI.GSTQUERY_API.gst_query_new_duration(Format.TIME);\n        assertNotNull(\"Query.newDuration returned null\", query);\n        assertTrue(\"Returned query not instance of DurationQuery\", query instanceof DurationQuery);\n    }\n    \n    @Test\n    public void getDurationQueryFormat() {\n        for (Format format : Format.values()) {\n            DurationQuery query = new DurationQuery(format);\n            assertEquals(\"Format returned from getFormat() is incorrect\" , format, query.getFormat());\n        }\n    }\n    @Test\n    public void getDuration() {\n        DurationQuery query = new DurationQuery(Format.TIME);\n        final long DURATION = 0xdeadbeef;\n        query.setDuration(Format.TIME, DURATION);\n        assertEquals(\"Incorrect duration returned\", DURATION, query.getDuration());\n    }\n    @Test \n    public void durationQueryToString() {\n        DurationQuery query = new DurationQuery(Format.TIME);\n        query.setDuration(Format.TIME, 1234);\n        String s = query.toString();\n        assertTrue(\"toString() did not return format\", s.contains(\"format=TIME\"));\n        assertTrue(\"toString() did not return duration\", s.contains(\"duration=1234\"));\n    }\n    @Test\n    public void gst_query_new_latency() {\n        Query query = GstQueryAPI.GSTQUERY_API.gst_query_new_latency();\n        assertNotNull(\"gst_query_new_latency() returned null\", query);\n        assertTrue(\"Returned query not instance of LatencyQuery\", query instanceof LatencyQuery);\n    }\n    @Test\n    public void latencyIsLive() {\n        LatencyQuery query = new LatencyQuery();\n        query.setLatency(true, 0, 0);\n        assertTrue(\"isLive not set to true\", query.isLive());\n        query.setLatency(false, 0, 0);\n        assertFalse(\"isLive not set to true\", query.isLive());\n    }\n    @Test \n    public void getMinimumLatency() {\n        LatencyQuery query = new LatencyQuery();\n//        final ClockTime MIN = ClockTime.fromMillis(13000);\n        final long MIN = TimeUnit.MILLISECONDS.toNanos(13000);\n        query.setLatency(false, MIN, ~0);\n        assertEquals(\"Min latency not set\", MIN, query.getMinimumLatency());\n    }\n    @Test \n    public void getMaximumLatency() {\n        LatencyQuery query = new LatencyQuery();\n//        final ClockTime MAX = ClockTime.fromMillis(123000);\n        final long MAX = TimeUnit.MILLISECONDS.toNanos(123000);\n        query.setLatency(false, 0, MAX);\n        assertEquals(\"Min latency not set\", MAX, query.getMaximumLatency());\n    }\n     \n    @Test \n    public void latencyQueryToString() {\n        LatencyQuery query = new LatencyQuery();\n        long minLatency = TimeUnit.MILLISECONDS.toNanos(13000); //ClockTime.fromMillis(13000);\n        long maxLatency = TimeUnit.MILLISECONDS.toNanos(200000);//ClockTime.fromMillis(200000);\n        query.setLatency(true, minLatency, maxLatency);\n        String s = query.toString();\n        assertTrue(\"toString() did not return isLive\", s.contains(\"live=true\"));\n        assertTrue(\"toString() did not return minLatency\", s.contains(\"min=\" + minLatency));\n        assertTrue(\"toString() did not return minLatency\", s.contains(\"max=\" + maxLatency));\n    }\n    \n    @Test public void segmentQuery() {\n        SegmentQuery query = new SegmentQuery(Format.TIME);\n//        ClockTime end = ClockTime.fromMillis(1000);\n        long end = TimeUnit.MILLISECONDS.toNanos(1000);\n        query.setSegment(1.0, Format.TIME, 0, end);\n        assertEquals(\"Format not set correctly\", Format.TIME, query.getFormat());\n        assertEquals(\"Start time not set correctly\", 0, query.getStart());\n        assertEquals(\"End time not set correctly\", end, query.getEnd());\n    }\n    @Test public void seekingQuery() {\n        SeekingQuery query = new SeekingQuery(Format.TIME);\n        long start = 0;\n        long end = TimeUnit.MILLISECONDS.toNanos(1000);\n        query.setSeeking(Format.TIME, true, start, end);\n        assertEquals(\"Format not set\", Format.TIME, query.getFormat());\n        assertEquals(\"Start time not set\", start, query.getStart());\n        assertEquals(\"End time not set\", end, query.getEnd());\n    }\n    @Test public void formatsQuery() {\n        Query query = GstQueryAPI.GSTQUERY_API.gst_query_new_formats();\n        assertNotNull(\"gst_query_new_latency() returned null\", query);\n        assertTrue(\"Returned query not instance of LatencyQuery\", query instanceof FormatsQuery);\n    }\n    @Test public void formatsQueryCount() {\n        FormatsQuery query = new FormatsQuery();\n        query.setFormats(Format.TIME, Format.PERCENT);\n        assertEquals(\"Wrong formats count\", 2, query.getCount());\n    }\n    @Test public void formatsQueryFormats() {\n        FormatsQuery query = new FormatsQuery();\n        query.setFormats(Format.TIME, Format.PERCENT);\n        assertEquals(\"First format incorrect\", Format.TIME, query.getFormat(0));\n        assertEquals(\"Second format incorrect\", Format.PERCENT, query.getFormat(1));\n        List<Format> formats = query.getFormats();\n        assertEquals(\"First format incorrect\", Format.TIME, formats.get(0));\n        assertEquals(\"Second format incorrect\", Format.PERCENT, formats.get(1));\n    }\n\n    @Test public void makeWriteable() {\n        Query query = new SegmentQuery(Format.TIME);\n        assertTrue(\"New query is not writable\", query.isWritable());\n        // Bumping the ref count makes this instance non writable\n//        GSTMINIOBJECT_API.gst_mini_object_ref(query);\n        Natives.ref(query);\n        assertFalse(\"Query with multiple references should not be writable\", query.isWritable());\n        // Now get a new reference that is writable\n        query = query.makeWritable();\n        assertTrue(\"Query not writable after makeWritable\", query.isWritable());\n    }\n    \n//    @Test public void testQueryTypeGetName() {\n//        assertEquals(QueryType.JITTER.getName(), \"jitter\");\n//    }\n    \n    @Test\n    public void gst_query_new_allocation() {\n        Query query = GstQueryAPI.GSTQUERY_API.gst_query_new_allocation(Caps.fromString(\"video/x-raw, format=I420\"), true);\n        assertNotNull(\"gst_query_new_allocation returned null\", query);\n        assertTrue(\"Returned query not instance of AllocationQuery\", query instanceof AllocationQuery);\n    }    \n    @Test\n    public void newAllocationQuery() {\n        Query query = new AllocationQuery(Caps.fromString(\"video/x-raw, format=I420\"), true);\n        assertNotNull(\"Query.newAllocationQuery returned null\", query);\n        assertTrue(\"Returned query not instance of AllocationQuery\", query instanceof AllocationQuery);\n    }\n    @Test\n    public void getCapsAllocationQuery() {\n    \tCaps caps = Caps.fromString(\"video/x-raw, format=I420\");\n    \tAllocationQuery query = new AllocationQuery(caps, true);\n        assertEquals(caps, query.getCaps());\n    }\n    @Test\n    public void needPoolAllocationQuery() {\n    \tCaps caps = Caps.fromString(\"video/x-raw, format=I420\");\n    \tAllocationQuery query = new AllocationQuery(caps, true);\n        assertEquals(true, query.isPoolNeeded());\n        query.dispose();\n    \tquery = new AllocationQuery(caps, false);\n        assertEquals(false, query.isPoolNeeded());\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/RegistryTest.java",
    "content": "/* \n * Copyright (c) 2007 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertNotNull;\nimport static org.junit.Assert.assertTrue;\n\nimport java.util.List;\n\nimport org.junit.AfterClass;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\n/**\n *\n * @author wayne\n */\npublic class RegistryTest {\n\n    public RegistryTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(\"RegistryTest\", new String[] {});\n    }\n    \n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n\n    @Test\n    public void testGet() {\n        Registry registry = Registry.get();\n        assertNotNull(\"Registry.getDefault() returned null\", registry);\n    }\n    \n    @Test\n    public void testGetPluginList() {\n        final String PLUGIN = \"vorbis\"; // Use something that is likely to be there\n        Registry registry = Registry.get();\n        List<Plugin> plugins = registry.getPluginList();\n        assertFalse(\"No plugins found\", plugins.isEmpty());\n        boolean pluginFound = false;\n        for (Plugin p : plugins) {\n            if (p.getName().equals(PLUGIN)) {\n                pluginFound = true;\n            }\n        }\n        assertTrue(PLUGIN + \" plugin not found\", pluginFound);\n    }\n    \n    @Test\n    public void testGetPluginListFiltered() {\n        final String PLUGIN = \"vorbis\"; // Use something that is likely to be there\n        Registry registry = Registry.get();\n        final boolean[] filterCalled = { false };\n        List<Plugin> plugins = registry.getPluginList(new Registry.PluginFilter() {\n            @Override\n            public boolean accept(Plugin plugin) {\n                filterCalled[0] = true;\n                return plugin.getName().equals(PLUGIN);\n            }\n        });\n        assertFalse(\"No plugins found\", plugins.isEmpty());\n        assertTrue(\"PluginFilter not called\", filterCalled[0]);\n        assertEquals(\"Plugin list should contain 1 item\", 1, plugins.size());\n        assertEquals(PLUGIN + \" plugin not found\", PLUGIN, plugins.get(0).getName());\n    }\n    \n    @Test\n    public void testGetPluginFeatureListByPlugin() {\n        final String PLUGIN = \"vorbis\"; // Use something that is likely to be there\n        final String FEATURE = \"vorbisdec\";\n        Registry registry = Registry.get();\n        List<PluginFeature> features = registry.getPluginFeatureListByPlugin(PLUGIN);\n        assertFalse(\"No plugin features found\", features.isEmpty());\n        boolean pluginFound = false;\n        for (PluginFeature p : features) {\n            if (p.getName().equals(FEATURE)) {\n                pluginFound = true;\n            }\n        }\n        assertTrue(PLUGIN + \" plugin not found\", pluginFound);\n    }\n    \n    @Test\n    public void testFindPluginFeature() {\n        PluginFeature f = Registry.get().lookupFeature(\"decodebin\");\n        assertNotNull(f);\n    }\n    \n    @Test\n    public void testFindPlugin() {\n        Plugin f = Registry.get().findPlugin(\"playback\");\n        assertNotNull(f);\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/SampleTest.java",
    "content": "/* \n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2020 John Cortell\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport static org.junit.Assert.*;\n\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.util.TestAssumptions;\nimport org.junit.AfterClass;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\npublic class SampleTest {\n\n    public SampleTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(Gst.getVersion(), \"SampleTest\");\n    }\n\n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n\n    @Test\n    public void testGetCaps() {\n        SampleTester.test((Sample sample) -> {\n            Caps caps = sample.getCaps();\n            Structure struct = caps.getStructure(0);\n            String name = struct.getName();\n            assertEquals(\"video/x-raw\", name);\n        });\n    }\n\n    @Test\n    public void testGetBuffer() {\n        SampleTester.test((Sample sample) -> {\n            Buffer buffer = sample.getBuffer();\n            assertEquals(1, buffer.getMemoryCount());\n        });\n    }\n\n    @Test\n    public void testSetBuffer() {\n        // since gst 1.16, the sample is recycled and keep a reference on the last buffer received\n        TestAssumptions.requireGstVersion(1, 16);\n\n        SampleTester.test((Sample sample) -> {\n\n            Buffer buffer = sample.getBuffer();\n\n            int refCount = buffer.getRefCount();\n\n            assertEquals(2, sample.getRefCount());\n\n            // make sample writable\n            Natives.unref(sample);\n\n            // force sample to release the buffer\n            sample.setBuffer(null);\n\n            Natives.ref(sample);\n\n            assertEquals(2, sample.getRefCount());\n\n            assertEquals(refCount - 1, buffer.getRefCount());\n        });\n    }\n\n    @Test\n    public void testSampleTester() {\n        try {\n            SampleTester.test(sample -> {\n                throw new IllegalStateException();\n            });\n        } catch (Throwable t) {\n            assertTrue(t instanceof AssertionError);\n            assertTrue(t.getCause() instanceof IllegalStateException);\n            return;\n        }\n        fail(\"No exception thrown\");\n    }\n\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/SampleTester.java",
    "content": "/*\n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2020 John Cortell\n *\n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertNotNull;\nimport static org.junit.Assert.fail;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.TimeoutException;\nimport java.util.function.Consumer;\n\nimport org.freedesktop.gstreamer.elements.AppSink;\n\n/**\n * Utility class for unit testing API that operates on a Sample.\n * <p>\n * Call {@link SampleTester#test(Consumer)} and pass a callback which will\n * perform the test on a Sample it is supplied. The callback runs on the\n * AppSink.NEW_SAMPLE thread. The sample is produced by a simple, ephemeral\n * pipeline that is fed by a video test source.\n */\npublic class SampleTester {\n\n    public static void test(Consumer<Sample> callback) {\n        test(callback, \"videotestsrc ! videoconvert ! appsink name=myappsink\");\n    }\n\n    public static void test(Consumer<Sample> callback, String pipelineDescription) {\n        test(callback, pipelineDescription, 0);\n    }\n\n    public static void test(Consumer<Sample> callback, String pipelineDescription, int skipFrames) {\n        assertNotNull(\"Pipeline description can not be null\", pipelineDescription);\n        assertFalse(\"Pipeline description can not be empty\", pipelineDescription.isEmpty());\n        Pipeline pipe = (Pipeline) Gst.parseLaunch(pipelineDescription);\n        assertNotNull(\"Unable to create Pipeline from pipeline description: \", pipe);\n\n        AppSink appSink = (AppSink) pipe.getElementByName(\"myappsink\");\n        appSink.set(\"emit-signals\", true);\n\n        NewSampleListener sampleListener = new NewSampleListener(callback, skipFrames);\n        appSink.connect(sampleListener);\n\n        pipe.play();\n\n        // Wait for the sample to arrive and for the client supplied test function to\n        // complete\n        try {\n            sampleListener.await(5000);\n        } catch (Exception ex) {\n            fail(\"Unexpected exception waiting for sample\\n\" + ex);\n        } finally {\n            pipe.stop();\n            appSink.disconnect(sampleListener);\n        }\n\n        // If the test threw an exception on the sample listener thread, throw it here\n        // (on the main thread)\n        if (sampleListener.exception != null) {\n            throw new AssertionError(sampleListener.exception);\n        }\n    }\n\n    private static class NewSampleListener implements AppSink.NEW_SAMPLE {\n\n        private final Consumer<Sample> callback;\n        private final int skipFrames;\n        private final CountDownLatch latch;\n\n        private Throwable exception;\n        private int counter = 0;\n\n        NewSampleListener(Consumer<Sample> callback) {\n            this(callback, 0);\n        }\n\n        NewSampleListener(Consumer<Sample> callback, int skip) {\n            this.callback = callback;\n            skipFrames = skip;\n            latch = new CountDownLatch(1);\n        }\n\n        @Override\n        public FlowReturn newSample(AppSink appSink) {\n            if (latch.getCount() > 0) {\n                Sample sample = appSink.pullSample();\n                if (counter < skipFrames) {\n                    counter++;\n                    sample.dispose();\n                    return FlowReturn.OK;\n                }\n                try {\n                    // Run the client's test logic on the sample (only once)\n                    try {\n                        callback.accept(sample);\n                    } catch (Throwable exc) {\n                        exception = exc;\n                    }\n                } finally {\n                    latch.countDown();\n                    sample.dispose();\n                }\n            }\n            return FlowReturn.OK;\n        }\n\n        void await(long millis) throws InterruptedException, TimeoutException {\n            if (!latch.await(millis, TimeUnit.MILLISECONDS)) {\n                throw new TimeoutException();\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/StreamInfoTest.java",
    "content": "package org.freedesktop.gstreamer;\n\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/StructureTest.java",
    "content": "/*\n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2009 Levente Farkas\n * Copyright (C) 2009 Tamas Korodi <kotyo@zamba.fm> \n * Copyright (C) 2007 Wayne Meissner\n * \n * This code is free software: you can redistribute it and/or modify it under \n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT \n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License \n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.GCancellable;\nimport org.freedesktop.gstreamer.lowlevel.GType;\nimport org.freedesktop.gstreamer.lowlevel.GValueAPI;\nimport org.junit.AfterClass;\nimport org.junit.Assert;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\nimport java.util.Arrays;\nimport java.util.List;\nimport org.freedesktop.gstreamer.util.TestAssumptions;\n\nimport static org.junit.Assert.*;\n\npublic class StructureTest {\n\n    private Structure structure;\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(Gst.getVersion(), \"StructureTest\");\n    }\n\n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n\n    @Before\n    public void setUp() {\n        structure = new Structure(\"nazgul\");\n    }\n\n    @Test\n    public void testGetName() {\n        assertEquals(\"nazgul\", structure.getName());\n    }\n\n    @Test\n    public void testGetValue() {\n        structure.setValue(\"uint\", GType.UINT, 9);\n        assertEquals(9, structure.getValue(\"uint\"));\n\n        try {\n            structure.getValue(\"noexist\");\n            fail(\"Structure.InvalidFieldException should have been thrown\");\n        } catch (Structure.InvalidFieldException e) {\n        }\n\n        structure.setDouble(\"double\", 9.0);\n        assertEquals(9.0, structure.getValue(\"double\"));\n\n        structure.setValue(\"bool\", GType.BOOLEAN, true);\n        assertEquals(true, structure.getValue(\"bool\"));\n\n    }\n\n    @Test\n    public void testGetValues() {\n        GValueAPI.GValueArray ar = new GValueAPI.GValueArray(2);\n        ar.append(new GValueAPI.GValue(GType.DOUBLE, 7.5));\n        ar.append(new GValueAPI.GValue(GType.DOUBLE, 14.3));\n        structure.setValue(\"valuearray\", GType.valueOf(GValueAPI.GValueArray.GTYPE_NAME), ar);\n        List<Double> doubles = structure.getValues(Double.class, \"valuearray\");\n        assertEquals(7.5, doubles.get(0), 0.001);\n        assertEquals(14.3, doubles.get(1), 0.001);\n        try {\n            List<String> strings = structure.getValues(String.class, \"valuearray\");\n            fail(\"Trying to extract the wrong type from GValueArray not throwing exception\");\n        } catch (Structure.InvalidFieldException ex) {\n        }\n        try {\n            List<Double> strings = structure.getValues(Double.class, \"non_existent\");\n            fail(\"Trying to extract a non-existent GValueArray field\");\n        } catch (Structure.InvalidFieldException ex) {\n        }\n    }\n\n    @Test\n    public void testGetInteger() {\n        structure.setInteger(\"int\", 9);\n        assertEquals(9, structure.getInteger(\"int\"));\n\n        structure.setInteger(\"int\", -9);\n        assertEquals(-9, structure.getInteger(\"int\"));\n    }\n\n    @Test\n    public void testGetIntegers() {\n        GValueAPI.GValueArray ar = new GValueAPI.GValueArray(2);\n        ar.append(new GValueAPI.GValue(GType.INT, 32));\n        ar.append(new GValueAPI.GValue(GType.INT, -49));\n        structure.setValue(\"integers\", GType.valueOf(GValueAPI.GValueArray.GTYPE_NAME), ar);\n        int[] in = new int[2];\n        int[] ints = structure.getIntegers(\"integers\", in);\n        assertTrue(in == ints);\n        assertEquals(32, ints[0]);\n        assertEquals(-49, ints[1]);\n\n        in = new int[1];\n        ints = structure.getIntegers(\"integers\", in);\n        assertFalse(in == ints);\n        assertEquals(32, ints[0]);\n        assertEquals(-49, ints[1]);\n\n        structure.setInteger(\"single_integer\", 18);\n        int[] single = structure.getIntegers(\"single_integer\", in);\n        assertTrue(in == single);\n        assertEquals(18, single[0]);\n    }\n\n    @Test\n    public void testGetDouble() {\n        structure.setDouble(\"double\", 9.0);\n        assertEquals(9.0, structure.getDouble(\"double\"), 0);\n\n        structure.setDouble(\"double\", -9.0);\n        assertEquals(-9.0, structure.getDouble(\"double\"), 0);\n    }\n\n    @Test\n    public void testGetDoubles() {\n        GValueAPI.GValueArray ar = new GValueAPI.GValueArray(2);\n        ar.append(new GValueAPI.GValue(GType.DOUBLE, 3.25));\n        ar.append(new GValueAPI.GValue(GType.DOUBLE, 79.6));\n        structure.setValue(\"doubles\", GType.valueOf(GValueAPI.GValueArray.GTYPE_NAME), ar);\n        double[] in = new double[2];\n        double[] doubles = structure.getDoubles(\"doubles\", in);\n        assertTrue(in == doubles);\n        assertEquals(3.25, doubles[0], 0.001);\n        assertEquals(79.6, doubles[1], 0.001);\n\n        in = new double[1];\n        doubles = structure.getDoubles(\"doubles\", in);\n        assertFalse(in == doubles);\n        assertEquals(3.25, doubles[0], 0.001);\n        assertEquals(79.6, doubles[1], 0.001);\n\n        structure.setDouble(\"single_double\", 18.2);\n        double[] single = structure.getDoubles(\"single_double\", in);\n        assertTrue(in == single);\n        assertEquals(18.2, single[0], 0.001);\n    }\n\n    @Test\n    public void testFraction() {\n        structure.setFraction(\"fraction\", 10, 1);\n\n        assertEquals(true, structure.hasField(\"fraction\"));\n\n        assertEquals(10, structure.getFraction(\"fraction\").getNumerator());\n        assertEquals(1, structure.getFraction(\"fraction\").getDenominator());\n\n        structure.setFraction(\"fraction\", 17, 10);\n        assertEquals(17, structure.getFraction(\"fraction\").getNumerator());\n        assertEquals(10, structure.getFraction(\"fraction\").getDenominator());\n    }\n\n    @Test\n    public void testValueListInteger() {\n        Caps caps = Caps.fromString(\"audio/x-raw,rate={44100,48000}\");\n        List<Integer> rates = caps.getStructure(0).getValues(Integer.class, \"rate\");\n        assertEquals(Arrays.asList(44100, 48000), rates);\n    }\n\n    @Test\n    public void testValueListStrings() {\n        Caps caps = Caps.fromString(\"video/x-raw,format={RGB, BGR, RGBx, BGRx}\");\n        List<String> formats = caps.getStructure(0).getValues(String.class, \"format\");\n        assertEquals(Arrays.asList(\"RGB\", \"BGR\", \"RGBx\", \"BGRx\"), formats);\n    }\n\n    @Test(expected = Structure.InvalidFieldException.class)\n    public void testValueListChecksType() {\n        Caps caps = Caps.fromString(\"video/x-raw,format={RGB, BGR, RGBx, BGRx}\");\n        caps.getStructure(0).getValues(Integer.class, \"format\");\n    }\n\n    @Test(expected = IllegalArgumentException.class)\n    public void testSetMistypedObject() {\n        GCancellable notACapsInstance = new GCancellable();\n        structure.setObject(\"whatever\", Caps.GTYPE_NAME, notACapsInstance);\n    }\n\n    @Test\n    public void testSetUntypedObject() {\n        GCancellable anyKindOfObject = new GCancellable();\n        structure.setObject(\"whatever\", GType.OBJECT.getTypeName(), anyKindOfObject);\n        Object value = structure.getValue(\"whatever\");\n        Assert.assertSame(anyKindOfObject, value);\n    }\n\n    @Test\n    public void testSetObject() {\n        GCancellable anyKindOfObject = new GCancellable();\n        structure.setObject(\"whatever\", GCancellable.GTYPE_NAME, anyKindOfObject);\n        Object value = structure.getValue(\"whatever\");\n        Assert.assertSame(anyKindOfObject, value);\n    }\n\n    @Test(expected = IllegalArgumentException.class)\n    public void testSetNullObject() {\n        structure.setObject(\"whatever\", GCancellable.GTYPE_NAME, null);\n        Object value = structure.getValue(\"whatever\");\n        Assert.assertNull(value);\n    }\n    \n    @Test\n    public void testIssue173() {\n        TestAssumptions.requireGstVersion(1, 16);\n        TestAssumptions.requireElement(\"srtsink\");\n        \n        Element srtsink = ElementFactory.make(\"srtsink\", \"srtsink\");\n        srtsink.set(\"uri\", \"srt://:8888/\");\n        Object stats = srtsink.get(\"stats\");\n        assertTrue(stats instanceof Structure);\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/TestPipe.java",
    "content": "/* \n * Copyright (c) 2007, 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer;\n\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\n\nclass TestPipe {\n\n    public final Pipeline pipe = new Pipeline(\"pipe\");\n    public final Element src = ElementFactory.make(\"fakesrc\", \"src\");\n    public final Element sink = ElementFactory.make(\"fakesink\", \"sink\");\n    public final String name;\n    private final CountDownLatch latch = new CountDownLatch(1);\n\n    public TestPipe() {\n        this(getInvokingMethod());\n    }\n    private static String getInvokingMethod() {\n        try {\n            throw new Exception();\n        } catch (Exception ex) {\n            return ex.getStackTrace()[2].getMethodName();\n        }\n    }\n    public TestPipe(String name) {\n        this.name = name;\n        pipe.addMany(src, sink);\n        Element.linkMany(src, sink);\n    }\n\n    public TestPipe run() {\n        try {\n            latch.await(250, TimeUnit.MILLISECONDS);\n        } catch (Exception ex) {\n        }\n        return this;\n    }\n\n    public TestPipe play() {\n        pipe.play();\n        return this;\n    }\n\n    public Bus getBus() {\n        return pipe.getBus();\n    }\n\n    public void quit() {\n        latch.countDown();\n    }\n\n    public void dispose() {\n        pipe.stop();\n    }\n\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/WebRTCBinTest.java",
    "content": "package org.freedesktop.gstreamer;\n\nimport org.freedesktop.gstreamer.glib.NativeEnum;\nimport org.freedesktop.gstreamer.webrtc.WebRTCICEGatheringState;\nimport org.freedesktop.gstreamer.webrtc.WebRTCPeerConnectionState;\nimport org.junit.Test;\n\nimport static org.junit.Assert.assertEquals;\n\npublic class WebRTCBinTest {\n    @Test\n    public void connectionStateTest() {\n        assertEquals(NativeEnum.fromInt(WebRTCPeerConnectionState.class, 0), WebRTCPeerConnectionState.NEW);\n        assertEquals(NativeEnum.fromInt(WebRTCPeerConnectionState.class, 1), WebRTCPeerConnectionState.CONNECTING);\n        assertEquals(NativeEnum.fromInt(WebRTCPeerConnectionState.class, 2), WebRTCPeerConnectionState.CONNECTED);\n        assertEquals(NativeEnum.fromInt(WebRTCPeerConnectionState.class, 3), WebRTCPeerConnectionState.DISCONNECTED);\n        assertEquals(NativeEnum.fromInt(WebRTCPeerConnectionState.class, 4), WebRTCPeerConnectionState.FAILED);\n        assertEquals(NativeEnum.fromInt(WebRTCPeerConnectionState.class, 5), WebRTCPeerConnectionState.CLOSED);\n    }\n\n    @Test\n    public void iceGatheringStateTest() {\n        assertEquals(NativeEnum.fromInt(WebRTCICEGatheringState.class, 0), WebRTCICEGatheringState.NEW);\n        assertEquals(NativeEnum.fromInt(WebRTCICEGatheringState.class, 1), WebRTCICEGatheringState.GATHERING);\n        assertEquals(NativeEnum.fromInt(WebRTCICEGatheringState.class, 2), WebRTCICEGatheringState.COMPLETE);\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/controller/InterpolationControlSourceTest.java",
    "content": "package org.freedesktop.gstreamer.controller;\n\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\nimport org.freedesktop.gstreamer.ClockTime;\nimport org.freedesktop.gstreamer.ControlBinding;\nimport org.freedesktop.gstreamer.ControlSource;\nimport org.freedesktop.gstreamer.Element;\nimport org.freedesktop.gstreamer.ElementFactory;\nimport org.freedesktop.gstreamer.GCTracker;\nimport org.freedesktop.gstreamer.Gst;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n *\n */\npublic class InterpolationControlSourceTest {\n\n    public InterpolationControlSourceTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() {\n        Gst.init(\"InterpolationControlSourceTest\");\n    }\n\n    @AfterClass\n    public static void tearDownClass() {\n    }\n\n    @Before\n    public void setUp() {\n    }\n\n    @After\n    public void tearDown() {\n    }\n\n    /**\n     * Test of setMode method, of class InterpolationControlSource.\n     */\n    @Test\n    public void testMode() {\n        InterpolationControlSource controller = new InterpolationControlSource();\n        InterpolationMode[] modes = InterpolationMode.values();\n        for (InterpolationMode mode : modes) {\n            controller.setMode(mode);\n            assertEquals(mode, controller.getMode());\n        }\n    }\n\n    @Test\n    public void testSetValue() {\n        List<ControlSource.TimedValue> timedValue\n                = Collections.singletonList(\n                        new ControlSource.TimedValue(ClockTime.fromSeconds(10), 0.5)\n                );\n        InterpolationControlSource controller = new InterpolationControlSource();\n        controller.set(timedValue.get(0).timestamp, timedValue.get(0).value);\n        assertEquals(timedValue, controller.getAll());\n    }\n\n    @Test\n    public void testSetValues() {\n        List<ControlSource.TimedValue> timedValues\n                = Stream.of(\n                        new ControlSource.TimedValue(ClockTime.fromSeconds(0), 0.0),\n                        new ControlSource.TimedValue(ClockTime.fromSeconds(1), 0.5),\n                        new ControlSource.TimedValue(ClockTime.fromSeconds(2), 0.2),\n                        new ControlSource.TimedValue(ClockTime.fromSeconds(4), 0.8)\n                ).collect(Collectors.toList());\n        InterpolationControlSource controller = new InterpolationControlSource();\n        controller.setFromList(timedValues);\n        assertEquals(timedValues, controller.getAll());\n    }\n\n    @Test\n    public void testLinearInterpolation() {\n        List<ControlSource.TimedValue> timedValues\n                = Stream.of(\n                        new ControlSource.TimedValue(ClockTime.fromSeconds(0), 0.0),\n                        new ControlSource.TimedValue(ClockTime.fromSeconds(1), 1.0)\n                ).collect(Collectors.toList());\n        InterpolationControlSource controller = new InterpolationControlSource();\n        controller.setMode(InterpolationMode.LINEAR);\n        controller.setFromList(timedValues);\n\n        Element volume = ElementFactory.make(\"volume\", \"volume\");\n        volume.addControlBinding(DirectControlBinding.create(volume, \"volume\", controller));\n        volume.syncValues(0);\n        assertEquals(0, ((Double) volume.get(\"volume\")).doubleValue(), 0.001);\n        volume.syncValues(ClockTime.fromMillis(500));\n        assertEquals(5, ((Double) volume.get(\"volume\")).doubleValue(), 0.001);\n        volume.syncValues(ClockTime.fromSeconds(1));\n        assertEquals(10, ((Double) volume.get(\"volume\")).doubleValue(), 0.001);\n\n    }\n\n    @Test\n    public void testLinearInterpolationAbsolute() {\n        List<ControlSource.TimedValue> timedValues\n                = Stream.of(\n                        new ControlSource.TimedValue(ClockTime.fromSeconds(0), 0.0),\n                        new ControlSource.TimedValue(ClockTime.fromSeconds(1), 5.0)\n                ).collect(Collectors.toList());\n        InterpolationControlSource controller = new InterpolationControlSource();\n        controller.setMode(InterpolationMode.LINEAR);\n        controller.setFromList(timedValues);\n\n        Element volume = ElementFactory.make(\"volume\", \"volume\");\n        ControlBinding binding = DirectControlBinding.createAbsolute(volume, \"volume\", controller);\n\n        assertEquals(2.5,\n                (Double) binding.getValue(ClockTime.fromMillis(500)),\n                0.01);\n\n        Object[] values = new Object[3];\n        binding.getValueArray(0, ClockTime.fromMillis(500), values);\n        assertEquals(0, (Double) values[0], 0.01);\n        assertEquals(2.5, (Double) values[1], 0.01);\n        assertEquals(5, (Double) values[2], 0.01);\n\n        volume.addControlBinding(binding);\n        volume.syncValues(0);\n        assertEquals(0, ((Double) volume.get(\"volume\")), 0.001);\n        volume.syncValues(ClockTime.fromMillis(500));\n        assertEquals(2.5, ((Double) volume.get(\"volume\")), 0.001);\n        volume.syncValues(ClockTime.fromSeconds(1));\n        assertEquals(5, ((Double) volume.get(\"volume\")), 0.001);\n\n    }\n\n    @Test\n    public void testGC() {\n        InterpolationControlSource controller = new InterpolationControlSource();\n        Element volume = ElementFactory.make(\"volume\", \"volume\");\n        ControlBinding binding = DirectControlBinding.create(volume, \"volume\", controller);\n        volume.addControlBinding(binding);\n        \n        GCTracker tracker = new GCTracker(controller);\n        controller = null;\n        binding = null;\n        volume = null;\n        \n        assertTrue(\"Controller not garbage collected\", tracker.waitGC());        \n        assertTrue(\"Controller not destroyed\", tracker.waitDestroyed());\n        \n    }\n\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/controller/TriggerControlSourceTest.java",
    "content": "package org.freedesktop.gstreamer.controller;\n\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.stream.Collectors;\nimport java.util.stream.Stream;\nimport org.freedesktop.gstreamer.ClockTime;\nimport org.freedesktop.gstreamer.ControlBinding;\nimport org.freedesktop.gstreamer.ControlSource;\nimport org.freedesktop.gstreamer.Element;\nimport org.freedesktop.gstreamer.ElementFactory;\nimport org.freedesktop.gstreamer.GCTracker;\nimport org.freedesktop.gstreamer.Gst;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\nimport static org.junit.Assert.*;\n\n/**\n *\n */\npublic class TriggerControlSourceTest {\n\n    public TriggerControlSourceTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() {\n        Gst.init(\"InterpolationControlSourceTest\");\n    }\n\n    @AfterClass\n    public static void tearDownClass() {\n    }\n\n    @Before\n    public void setUp() {\n    }\n\n    @After\n    public void tearDown() {\n    }\n\n\n    @Test\n    public void testTolerance() {\n        List<ControlSource.TimedValue> timedValues\n                = Stream.of(\n                        new ControlSource.TimedValue(ClockTime.fromSeconds(0), 0.5),\n                        new ControlSource.TimedValue(ClockTime.fromSeconds(2), 1.0)\n                ).collect(Collectors.toList());\n        TriggerControlSource controller = new TriggerControlSource();\n        controller.setFromList(timedValues);\n\n        Element volume = ElementFactory.make(\"volume\", \"volume\");\n        volume.addControlBinding(DirectControlBinding.create(volume, \"volume\", controller));\n        volume.syncValues(0);\n        assertEquals(5, ((Double) volume.get(\"volume\")), 0.001);\n        volume.set(\"volume\", 0);\n        volume.syncValues(ClockTime.fromSeconds(1));\n        assertEquals(0, ((Double) volume.get(\"volume\")), 0.001);\n        volume.syncValues(ClockTime.fromSeconds(2));\n        assertEquals(10, ((Double) volume.get(\"volume\")), 0.001);\n        \n        controller.setTolerance(ClockTime.fromMillis(500));\n        volume.syncValues(ClockTime.fromMillis(450));\n        assertEquals(5, ((Double) volume.get(\"volume\")), 0.001);\n        volume.set(\"volume\", 0);\n        volume.syncValues(ClockTime.fromMillis(550));\n        assertEquals(0, ((Double) volume.get(\"volume\")), 0.001);\n        volume.syncValues(ClockTime.fromMillis(1650));\n        assertEquals(10, ((Double) volume.get(\"volume\")), 0.001);\n\n    }\n\n    @Test\n    public void testGC() {\n        TriggerControlSource controller = new TriggerControlSource();\n        Element volume = ElementFactory.make(\"volume\", \"volume\");\n        ControlBinding binding = DirectControlBinding.create(volume, \"volume\", controller);\n        volume.addControlBinding(binding);\n        \n        GCTracker tracker = new GCTracker(controller);\n        controller = null;\n        binding = null;\n        volume = null;\n        \n        assertTrue(\"Controller not garbage collected\", tracker.waitGC());        \n        assertTrue(\"Controller not destroyed\", tracker.waitDestroyed());\n        \n    }\n\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/elements/PlayBinTest.java",
    "content": "/* \n * Copyright (c) 2021 Neil C Smith\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\npackage org.freedesktop.gstreamer.elements;\n\nimport java.net.URI;\nimport java.util.EnumSet;\nimport java.util.Set;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicReference;\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.ElementFactory;\nimport org.freedesktop.gstreamer.GCTracker;\nimport org.freedesktop.gstreamer.Gst;\nimport org.freedesktop.gstreamer.util.TestAssumptions;\nimport org.junit.AfterClass;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Tests for PlayBin.\n */\npublic class PlayBinTest {\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(Gst.getVersion(), \"PlayBinTest\");\n    }\n\n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n\n    @Test\n    public void testFlags() {\n        PlayBin playbin = new PlayBin(\"playbin\");\n        Set<PlayFlags> defaultFlags = EnumSet.of(\n                PlayFlags.SOFT_COLORBALANCE,\n                PlayFlags.DEINTERLACE,\n                PlayFlags.SOFT_VOLUME,\n                PlayFlags.TEXT,\n                PlayFlags.AUDIO,\n                PlayFlags.VIDEO\n        );\n        Set<PlayFlags> flags = playbin.getFlags();\n        assertEquals(\"PlayBin flags not expected defaults\", defaultFlags, flags);\n\n        flags.add(PlayFlags.VIS);\n        flags.remove(PlayFlags.DEINTERLACE);\n        playbin.setFlags(flags);\n\n        flags = playbin.getFlags();\n        assertTrue(\"VIS flag not set\", flags.contains(PlayFlags.VIS));\n        assertFalse(\"Deinterlace not removed from playbin flags\",\n                flags.contains(PlayFlags.DEINTERLACE));\n\n        playbin.dispose();\n\n    }\n\n    @Test\n    public void testSourceSetupSignal() throws Exception {\n\n        PlayBin playbin = new PlayBin(\"playbin\", URI.create(\"appsrc:/\"));\n        AtomicReference<AppSrc> sourceRef = new AtomicReference<>(null);\n        playbin.connect((PlayBin.SOURCE_SETUP) ((p, e) -> {\n            if (e instanceof AppSrc) {\n                AppSrc appSrc = (AppSrc) e;\n                appSrc.setCaps(Caps.fromString(\"video/x-raw, format=xRGB, width=640, height=480\"));\n                sourceRef.set(appSrc);\n            }\n        }));\n        playbin.setVideoSink(ElementFactory.make(\"fakesink\", \"videosink\"));\n        playbin.play();\n        playbin.getState(200, TimeUnit.MILLISECONDS);\n\n        AppSrc src = sourceRef.getAndSet(null);\n        assertNotNull(src);\n\n        GCTracker sourceTracker = new GCTracker(src);\n        GCTracker playbinTracker = new GCTracker(playbin);\n\n        playbin.stop();\n\n        src = null;\n        playbin = null;\n\n        assertTrue(\"AppSrc not garbage collected\", sourceTracker.waitGC());\n        assertTrue(\"AppSrc not destroyed\", sourceTracker.waitDestroyed());\n        assertTrue(\"PlayBin not garbage collected\", playbinTracker.waitGC());\n        assertTrue(\"PlayBin not destroyed\", playbinTracker.waitDestroyed());\n\n    }\n\n    @Test\n    public void testElementSetupSignal() throws Exception {\n\n        TestAssumptions.requireGstVersion(1, 10);\n        PlayBin playbin = new PlayBin(\"playbin\", URI.create(\"appsrc:/\"));\n        AtomicReference<AppSrc> sourceRef = new AtomicReference<>(null);\n        playbin.connect((PlayBin.ELEMENT_SETUP) ((p, e) -> {\n            if (e instanceof AppSrc) {\n                AppSrc appSrc = (AppSrc) e;\n                sourceRef.set(appSrc);\n            }\n        }));\n        playbin.setVideoSink(ElementFactory.make(\"fakesink\", \"videosink\"));\n        playbin.play();\n        playbin.getState(200, TimeUnit.MILLISECONDS);\n\n        AppSrc src = sourceRef.getAndSet(null);\n        assertNotNull(src);\n\n        GCTracker sourceTracker = new GCTracker(src);\n        GCTracker playbinTracker = new GCTracker(playbin);\n\n        playbin.stop();\n\n        src = null;\n        playbin = null;\n\n        assertTrue(\"AppSrc not garbage collected\", sourceTracker.waitGC());\n        assertTrue(\"AppSrc not destroyed\", sourceTracker.waitDestroyed());\n        assertTrue(\"PlayBin not garbage collected\", playbinTracker.waitGC());\n        assertTrue(\"PlayBin not destroyed\", playbinTracker.waitDestroyed());\n\n    }\n\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/event/EventTest.java",
    "content": "/* \n * Copyright (c) 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.event;\n\nimport org.freedesktop.gstreamer.event.QOSType;\nimport org.freedesktop.gstreamer.event.Event;\nimport org.freedesktop.gstreamer.event.EventType;\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertNotNull;\nimport static org.junit.Assert.assertTrue;\nimport static org.junit.Assert.fail;\n\nimport java.lang.ref.WeakReference;\nimport java.util.EnumSet;\nimport java.util.concurrent.TimeUnit;\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.ClockTime;\nimport org.freedesktop.gstreamer.Format;\nimport org.freedesktop.gstreamer.GCTracker;\nimport org.freedesktop.gstreamer.Gst;\nimport org.freedesktop.gstreamer.Structure;\nimport org.freedesktop.gstreamer.TagList;\n\nimport org.freedesktop.gstreamer.event.BufferSizeEvent;\nimport org.freedesktop.gstreamer.event.CapsEvent;\nimport org.freedesktop.gstreamer.event.EOSEvent;\nimport org.freedesktop.gstreamer.event.FlushStartEvent;\nimport org.freedesktop.gstreamer.event.FlushStopEvent;\nimport org.freedesktop.gstreamer.event.LatencyEvent;\nimport org.freedesktop.gstreamer.event.QOSEvent;\nimport org.freedesktop.gstreamer.event.ReconfigureEvent;\nimport org.freedesktop.gstreamer.event.SeekEvent;\nimport org.freedesktop.gstreamer.event.SegmentEvent;\nimport org.freedesktop.gstreamer.event.StepEvent;\nimport org.freedesktop.gstreamer.event.StreamStartEvent;\nimport org.freedesktop.gstreamer.event.TagEvent;\nimport org.freedesktop.gstreamer.lowlevel.GstAPI;\nimport static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API;\nimport org.junit.AfterClass;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\n/**\n *\n * @author wayne\n */\npublic class EventTest {\n    public EventTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(\"EventTest\", new String[] {});\n    }\n    \n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n\n    @Test public void verifyFlags() {\n        // Verify that the flags in the enum match the native ones.\n        EventType[] types = EventType.values();\n        for (EventType t : types) {\n            int flags = GSTEVENT_API.gst_event_type_get_flags(t);\n            assertEquals(\"Incorrect flags for: \" + t.name(), flags, t.intValue() & 0xFF);\n        }\n    }\n    @Test public void createEOSEvent() throws Exception {\n        new EOSEvent();\n    }\n    @Test public void createFlushStartEvent() throws Exception {\n        new FlushStartEvent();\n    }\n    @Test public void createFlushStopEvent() throws Exception {\n        new FlushStopEvent();\n    }\n    @Test public void createLatencyEvent() throws Exception {\n        new LatencyEvent(ClockTime.ZERO);\n    }\n    @Test public void createSegmentEvent() throws Exception {\n        GstAPI.GstSegmentStruct struct = new GstAPI.GstSegmentStruct();\n        struct.flags = 0;\n        struct.rate = 1.0;\n        struct.applied_rate = 1.0;\n        struct.format = Format.TIME;\n        new SegmentEvent(struct);\n    }\n    @Test public void createCapsEvent() throws Exception {\n        new CapsEvent(Caps.fromString(\"video/x-raw,format=I420\"));\n    }\n    @Test public void createReconfigureEvent() throws Exception {\n        new ReconfigureEvent();\n    }\n    @Test public void createStreamStartEvent() throws Exception {\n        new StreamStartEvent(\"a stream_id\");\n    }\n    @Test public void createStepEvent() throws Exception {\n        new StepEvent(Format.BUFFERS, 1, 1, true, false);\n    }\n    @Test public void gst_event_new_eos() {\n        Event eos = GSTEVENT_API.gst_event_new_eos();\n        assertNotNull(\"gst_event_new_eos returned null\", eos);\n        assertTrue(\"gst_event_new_eos returned a non-EOS event\", eos instanceof EOSEvent);\n    }\n    @Test public void gst_event_new_flush_start() {\n        Event ev = GSTEVENT_API.gst_event_new_flush_start();\n        assertNotNull(\"gst_event_new_flush_start returned null\", ev);\n        assertTrue(\"gst_event_new_flush_start returned a non-FLUSH_START event\", ev instanceof FlushStartEvent);\n    }\n    @Test public void gst_event_new_flush_stop() {\n        Event ev = GSTEVENT_API.gst_event_new_flush_stop();\n        assertNotNull(\"gst_event_new_flush_stop returned null\", ev);\n        assertTrue(\"gst_event_new_flush_stop returned a non-FLUSH_STOP event\", ev instanceof FlushStopEvent);\n    }\n    @Test public void gst_event_new_latency() {\n        Event ev = GSTEVENT_API.gst_event_new_latency(0);\n        assertNotNull(\"gst_event_new_latency returned null\", ev);\n        assertTrue(\"gst_event_new_latency returned a non-LATENCY event\", ev instanceof LatencyEvent);\n    }\n    @Test public void gst_event_new_new_segment() {\n        GstAPI.GstSegmentStruct struct = new GstAPI.GstSegmentStruct();\n        struct.flags = 0;\n        struct.rate = 1.0;\n        struct.applied_rate = 1.0;\n        struct.format = Format.TIME;\n        Event ev = GSTEVENT_API.gst_event_new_segment(struct);\n        assertNotNull(\"gst_event_new_latency returned null\", ev);\n        assertTrue(\"gst_event_new_latency returned a non-NEWSEGMENT event\", ev instanceof SegmentEvent);\n    }\n    @Test public void getLatency() {\n//        final ClockTime MAGIC = ClockTime.valueOf(0xdeadbeef, TimeUnit.NANOSECONDS);\n        long MAGIC = 0xdeadbeef;\n        LatencyEvent ev = new LatencyEvent(MAGIC);\n        assertEquals(\"Incorrect latency returned\", MAGIC, ev.getLatency());\n    }\n    @Test public void NewSegment_getRate() {\n        final double RATE = (double) 0xdeadbeef;\n        SegmentEvent ev = new SegmentEvent(new GstAPI.GstSegmentStruct(0, RATE, RATE, Format.TIME, 0, 0, 0, 0, 0, 0, 0));\n        assertEquals(\"Incorrect rate returned from getRate\", RATE, ev.getSegment().rate, 0.0);\n    }\n    @Test public void NewSegment_getStart() {\n        final long START = 0xdeadbeefL;\n        SegmentEvent ev = new SegmentEvent(new GstAPI.GstSegmentStruct(0, 0.1, 0.1, Format.TIME, 0, 0, START, -1L, 0, 0, 0));\n        assertEquals(\"Incorrect rate returned from getStart\", START, ev.getSegment().start);\n    }\n    @Test public void NewSegment_getStop() {\n        final long STOP = 0xdeadbeefL;\n        SegmentEvent ev = new SegmentEvent(new GstAPI.GstSegmentStruct(0, 0.1, 0.1, Format.TIME, 0, 0, 0L, STOP, 0, 0, 0));\n        assertEquals(\"Incorrect rate returned from getRate\", STOP, ev.getSegment().stop);\n    }\n    @Test public void gst_event_new_tag() {\n        Event ev = GSTEVENT_API.gst_event_new_tag(new TagList());\n        assertNotNull(\"gst_event_new_tag returned null\", ev);\n        assertTrue(\"gst_event_new_tag returned a non-TAG event\", ev instanceof TagEvent);\n    }\n    @Test public void TagEvent_testGC() throws Exception {\n        TagEvent ev = new TagEvent(new TagList());\n        @SuppressWarnings(\"unused\")\n        TagList tl = ev.getTagList();\n        WeakReference<Event> evRef = new WeakReference<Event>(ev);\n        ev = null;\n        assertFalse(\"Event ref collected before TagList is unreferenced\", GCTracker.waitGC(evRef));\n        tl = null;\n        assertTrue(\"Event ref not collected after TagList is unreferenced\", GCTracker.waitGC(evRef));\n    }\n    @Test public void Event_testGC() throws Exception {\n        Event ev = new LatencyEvent(100);\n        @SuppressWarnings(\"unused\")\n        Structure s = ev.getStructure();\n        WeakReference<Event> evRef = new WeakReference<Event>(ev);\n        ev = null;\n        assertFalse(\"Event ref collected before Structure is unreferenced\", GCTracker.waitGC(evRef));\n        s = null;\n        assertTrue(\"Event ref not collected after Structure is unreferenced\", GCTracker.waitGC(evRef));\n    }\n    @Test public void gst_event_new_buffer_size() {\n        final long MIN = 0x1234;\n        final long MAX = 0xdeadbeef;\n        final boolean ASYNC = false;\n        Event ev = GSTEVENT_API.gst_event_new_buffer_size(Format.BYTES, MIN, MAX, ASYNC);\n        assertNotNull(\"gst_event_new_buffer_size returned null\", ev);\n        assertTrue(\"gst_event_new_buffer_size returned a non-BUFFERSIZE event\", ev instanceof BufferSizeEvent);\n    }\n    @Test public void BufferSize_getMinimumSize() {\n        final long MIN = 0x1234;\n        final long MAX = 0xdeadbeef;\n        final boolean ASYNC = false;\n        BufferSizeEvent ev = (BufferSizeEvent) GSTEVENT_API.gst_event_new_buffer_size(Format.BYTES, MIN, MAX, ASYNC);\n        assertEquals(\"Wrong minimum size stored\", MIN, ev.getMinimumSize());\n    }\n    @Test public void BufferSize_getMaximumSize() {\n        final long MIN = 0x1234;\n        final long MAX = 0xdeadbeef;\n        final boolean ASYNC = false;\n        BufferSizeEvent ev = (BufferSizeEvent) GSTEVENT_API.gst_event_new_buffer_size(Format.BYTES, MIN, MAX, ASYNC);\n        assertEquals(\"Wrong minimum size stored\", MAX, ev.getMaximumSize());\n    }\n    @Test public void BufferSize_isAsync() {\n        final long MIN = 0x1234;\n        final long MAX = 0xdeadbeef;\n        final boolean ASYNC = false;\n        BufferSizeEvent ev = (BufferSizeEvent) GSTEVENT_API.gst_event_new_buffer_size(Format.BYTES, MIN, MAX, ASYNC);\n        assertEquals(\"Wrong minimum size stored\", ASYNC, ev.isAsync());\n        BufferSizeEvent ev2 = (BufferSizeEvent) GSTEVENT_API.gst_event_new_buffer_size(Format.BYTES, MIN, MAX, !ASYNC);\n        assertEquals(\"Wrong minimum size stored\", !ASYNC, ev2.isAsync());\n    }\n    @Test public void gst_event_new_qos() {\n        Event ev = GSTEVENT_API.gst_event_new_qos(QOSType.THROTTLE, 0.0, 0, ClockTime.NONE);\n        assertNotNull(\"gst_event_new_qos returned null\", ev);\n        assertTrue(\"gst_event_new_qos returned a non-QOS event\", ev instanceof QOSEvent);\n    }\n    @Test public void QOS_getProportion() {\n        final double PROPORTION = (double) 0xdeadbeef;\n        QOSEvent ev = new QOSEvent(QOSType.THROTTLE, PROPORTION, 0, ClockTime.ZERO);\n        assertEquals(\"Wrong proportion\", PROPORTION, ev.getProportion(), 0d);\n    }\n    @Test public void QOS_getDifference() {\n        long DIFF = 0x4096;\n        QOSEvent ev = new QOSEvent(QOSType.THROTTLE, 0d, DIFF, ClockTime.ZERO);\n        assertEquals(\"Wrong difference\", DIFF, ev.getDifference());\n    }\n    @Test public void QOS_getTimestamp() {\n        final long STAMP = 0xdeadbeef;\n        QOSEvent ev = new QOSEvent(QOSType.THROTTLE, 0d, 0, STAMP);\n        assertEquals(\"Wrong timestamp\", STAMP, ev.getTimestamp());\n    }\n    @Test\n    public void QOS_getType() {\n        final long STAMP = 0xdeadbeef;\n        QOSEvent ev = new QOSEvent(QOSType.THROTTLE, 0d, 0, STAMP);\n        assertEquals(\"Wrong QOSType\", QOSType.THROTTLE, ev.getType());\n    }\n    @Test public void gst_event_new_seek() {\n        Event ev = GSTEVENT_API.gst_event_new_seek(1.0, Format.TIME, 0, \n                SeekType.SET, 0, SeekType.SET, 0);\n        assertNotNull(\"gst_event_new_seek returned null\", ev);\n        assertTrue(\"gst_event_new_seek returned a non-SEEK event\", ev instanceof SeekEvent);\n    }\n    @Test public void Seek_getFormat() {\n        for (Format FORMAT : new Format[] { Format.TIME, Format.BYTES }) {\n            SeekEvent ev = new SeekEvent(1.0, FORMAT, EnumSet.noneOf(SeekFlags.class), \n                    SeekType.SET, 0, SeekType.SET, 0);\n            assertEquals(\"Wrong format in SeekEvent\", FORMAT, ev.getFormat());\n        }\n    }\n    @Test public void Seek_getStartType() {\n        for (SeekType TYPE : new SeekType[] { SeekType.SET, SeekType.END }) {\n            SeekEvent ev = new SeekEvent(1.0, Format.TIME, EnumSet.noneOf(SeekFlags.class), \n                    TYPE, 0, SeekType.NONE, 0);\n            assertEquals(\"Wrong startType in SeekEvent\", TYPE, ev.getStartType());\n        }\n    }\n    @Test public void Seek_getStopType() {\n        for (SeekType TYPE : new SeekType[] { SeekType.SET, SeekType.END }) {\n            SeekEvent ev = new SeekEvent(1.0, Format.TIME, EnumSet.noneOf(SeekFlags.class), \n                    SeekType.NONE, 0, TYPE, 0);\n            assertEquals(\"Wrong stopType in SeekEvent\", TYPE, ev.getStopType());\n        }\n    }\n    @Test public void Seek_getStart() {\n        final long START = 0xdeadbeef;\n        SeekEvent ev = new SeekEvent(1.0, Format.TIME, EnumSet.noneOf(SeekFlags.class), \n                    SeekType.SET, START, SeekType.SET, -1);\n            assertEquals(\"Wrong start in SeekEvent\", START, ev.getStart());\n    }\n    @Test public void Seek_getStop() {\n        final long STOP = 0xdeadbeef;\n        SeekEvent ev = new SeekEvent(1.0, Format.TIME, EnumSet.noneOf(SeekFlags.class), \n                    SeekType.SET, 0, SeekType.SET, STOP);\n            assertEquals(\"Wrong stop in SeekEvent\", STOP, ev.getStop());\n    }\n    @Test public void Seek_rateZero() {\n        try {\n            new SeekEvent(0.0, Format.TIME, EnumSet.noneOf(SeekFlags.class), \n                    SeekType.SET, 0, SeekType.SET, -1);\n            fail(\"A rate of 0.0 should throw an exception\");\n        } catch (IllegalArgumentException ex) {\n            \n        }\n    }\n    @Test public void gst_event_new_caps() {\n        Event ev = GSTEVENT_API.gst_event_new_caps(Caps.fromString(\"video/x-raw,format=I420\"));\n        assertNotNull(\"gst_event_new_caps returned null\", ev);\n        assertTrue(\"gst_event_new_caps returned a non-CAPS event\", ev instanceof CapsEvent);\n    }\n    @Test public void gst_event_new_reconfigure() {\n        Event ev = GSTEVENT_API.gst_event_new_reconfigure();\n        assertNotNull(\"gst_event_new_reconfigure returned null\", ev);\n        assertTrue(\"gst_event_new_reconfigure returned a non-RECONFIGURE event\", ev instanceof ReconfigureEvent);\n    }\n    @Test public void gst_event_new_stream_start() {\n        Event ev = GSTEVENT_API.gst_event_new_stream_start(\"a stream id\");\n        assertNotNull(\"gst_event_new_stream_start returned null\", ev);\n        assertTrue(\"gst_event_new_stream_start returned a non-STREAM-START event\", ev instanceof StreamStartEvent);\n    }\n    @Test public void gst_event_new_step() {\n        Event ev = GSTEVENT_API.gst_event_new_step(Format.BUFFERS, 1, 1, true, false);\n        assertNotNull(\"gst_event_new_step returned null\", ev);\n        assertTrue(\"gst_event_new_step returned a non-STEP event\", ev instanceof StepEvent);\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/lowlevel/GValueTest.java",
    "content": "/* \n * Copyright (c) 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.lowlevel.GNative;\nimport org.freedesktop.gstreamer.lowlevel.GValueAPI;\nimport org.freedesktop.gstreamer.lowlevel.GType;\nimport org.freedesktop.gstreamer.lowlevel.GstElementFactoryAPI;\nimport static org.junit.Assert.*;\n\nimport java.util.HashMap;\n\nimport org.freedesktop.gstreamer.Element;\nimport org.freedesktop.gstreamer.ElementFactory;\nimport org.freedesktop.gstreamer.Gst;\nimport org.freedesktop.gstreamer.lowlevel.GValueAPI.GValue;\nimport org.freedesktop.gstreamer.lowlevel.GValueAPI.GValueArray;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\nimport com.sun.jna.Library;\nimport com.sun.jna.Pointer;\n\n/**\n *\n */\npublic class GValueTest {\n    private static final GValueAPI api = GValueAPI.GVALUE_API;\n\n    public interface GValueTestAPI extends Library {\n\n        @SuppressWarnings(\"serial\")\n        GValueTestAPI API = GNative.loadLibrary(\"gobject-2.0\", GValueTestAPI.class,\n                new HashMap<String, Object>() {\n        });\n\n        void g_value_set_object(Pointer value, Pointer obj);\n\n        Pointer g_value_get_object(Pointer pointer);\n\n    }\n\t\n    public GValueTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(\"GValueTest\", new String[] {});\n    }\n    \n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n\n    @Before\n    public void setUp() {\n    }\n\n    @After\n    public void tearDown() {\n    }\n\n    @Test public void testGValueArray() throws Exception {\n        testGValueArray(new GValueArray());\n        testGValueArray(new GValueArray(2));\n        testGValueArray(new GValueArray(5));\n    }\n    \n    private void testGValueArray(GValueArray gva) throws Exception {\n        \n        gva.append(new GValue(GType.INT, 5));        \n        gva.append(new GValue(GType.DOUBLE, 5.0));        \n        gva.append(new GValue(GType.STRING, \"omanipadmihoom\"));\n        \n        assertEquals(\"vrong n_value\", 3, gva.getNValues());\n        \n        assertEquals(\"value mismatch\", 5, gva.getValue(0));\n        assertEquals(\"value mismatch\", 5.0, gva.getValue(1));\n        assertEquals(\"value mismatch\", \"omanipadmihoom\", gva.getValue(2));\n        \n        gva.free();\n    }\n    \n    @Test public void testInitSet() throws Exception {\n        \n        GValue v = new GValue(GType.INT);\n        \n        assertEquals(\"type mismatch\", GType.INT, v.getType());  \n        \n        try {\n            v.setValue(null);\n            fail(\"IllegalArgumentException should have been thrown\");\n        } catch (IllegalArgumentException e) {}\n                \n        try {\n            v.setValue(0.2);\n            fail(\"IllegalArgumentException should have been thrown\");\n        } catch (ClassCastException e) {}\n        \n\n        v.setValue(42);\n        \n        assertEquals(\"wrong value\", 42, v.getValue());\n        \n    }\n\n    @Test public void testInitValue() throws Exception {\n        \n        GValue v;\n        \n        \n        try {\n            v = new GValue(GType.INT, null);\n            fail(\"IllegalArgumentException should have been thrown\");\n        } catch (IllegalArgumentException e) {}\n                \n        try {\n            v = new GValue(GType.INT, 0.2);\n            fail(\"IllegalArgumentException should have been thrown\");\n        } catch (ClassCastException e) {}\n        \n        v = new GValue(GType.DOUBLE, 42.0);\n        \n        assertEquals(\"type mismatch\", GType.DOUBLE, v.getType());  \n\n        \n        assertEquals(\"wrong value\", 42.0, v.getValue());\n        \n    }\n\n    @Test public void testInt() throws Exception {\n    \tGValue v = new GValue();\n    \tapi.g_value_init(v, GType.INT);\n    \tapi.g_value_set_int(v, 5);\n    \t\n    \tassertEquals(\"int value mismatch\", 5, v.getValue());\n    \t\n    \tapi.g_value_set_int(v, 6);\n    \t\n    \tassertEquals(\"int value mismatch\", 6, v.getValue());\n    \t\n    \tassertTrue(\"type mismatch\", v.getValue() instanceof Integer);\n    \t\n    \t\n    }\n\n    /**\n     * Test type conversion of object value when using\n     * an object created 'the proper way'\n     */\n    @Test public void testObjectPtrRef() throws Exception {\n\t// the following probably puts 'e' into the object reference map\n\n    \tElement e = ElementFactory.make(\"fakesink\", \"fakesink\");\n    \t\n    \tGValue v = new GValue();\n    \tapi.g_value_init(v, GType.OBJECT);\n    \tapi.g_value_set_object(v, e);\n    \t\n    \tObject obj = v.getValue();\n    \t\n    \tassertTrue(\"type mismatch\", obj instanceof Element);\n\n    \tassertEquals(\"object mismatch\", e, obj);\n    }\n    \n    /**\n     * Test type conversion of object value trying to bypass the object reference map\n     */\n     @Test public void testObjectTypeMap() throws Exception {\n\n\t Pointer p;\n\t \n\t {\n\t     /*\n\t      * Not using ElementFactory.make() here probably prevents the element \n\t      * from being placed in the object reference map and therefore forces\n\t      * type mapper conversion - what we want to test\n\t      */\n\t     \n\t     ElementFactory factory = GstElementFactoryAPI.GSTELEMENTFACTORY_API.gst_element_factory_find(\"videotestsrc\");\n\t     p = GstElementFactoryAPI.GSTELEMENTFACTORY_API.ptr_gst_element_factory_create(factory, \"videotestsrc\");\n\t }\n    \t    \t\n    \tGValue v = new GValue();\n    \tapi.g_value_init(v, GType.OBJECT);\n    \t\n    \tGValueTestAPI.API.g_value_set_object(v.getPointer(), p);\n    \t\n    \tObject obj = v.getValue();\n\n    \tassertTrue(\"type mismatch\", obj instanceof Element);\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/lowlevel/LowLevelStructureTest.java",
    "content": "package org.freedesktop.gstreamer.lowlevel;\n\nimport static org.junit.Assert.assertTrue;\n\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Modifier;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.logging.Level;\nimport java.util.logging.Logger;\n\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\nimport com.sun.jna.Structure;\nimport java.util.Arrays;\nimport org.freedesktop.gstreamer.Gst;\n\npublic class LowLevelStructureTest {\n\n    private final static Logger LOG = Logger.getLogger(LowLevelStructureTest.class.getName());\n    private static List<Class<? extends Structure>> structs;\n    private static List<Class<? extends Structure>> untestable;\n\n    public LowLevelStructureTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() {\n        initStructList();\n    }\n\n    @AfterClass\n    public static void tearDownClass() {\n    }\n\n    @Before\n    public void setUp() {\n        if (untestable == null) {\n            untestable = new ArrayList<Class<? extends Structure>>();\n        }\n    }\n\n    @After\n    public void tearDown() {\n    }\n\n    @Test\n    public void runTest() {\n\n        for (Class<? extends Structure> struct : structs) {\n            testStruct(struct);\n        }\n\n        if (!untestable.isEmpty()) {\n            StringBuilder builder = new StringBuilder(\"UNTESTABLE:\\n\");\n            for (Class<? extends Structure> struct : untestable) {\n                builder.append(struct.getName());\n                builder.append(\"\\n\");\n            }\n            LOG.log(Level.WARNING, builder.toString());\n        }\n\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private void testStruct(Class<? extends Structure> struct) {\n        LOG.log(Level.INFO, \"Testing {0}\", struct.getName());\n        Structure inst = null;\n        List<String> fields = null;\n        try {\n            inst = struct.newInstance();\n        } catch (Exception ex) {\n//            try {\n//                Constructor<? extends Structure> con = struct.getConstructor(Pointer.class);\n//                inst = con.newInstance(Pointer.NULL);\n//            } catch (Exception ex1) {\n            untestable.add(struct);\n//                assertTrue(false);\n            return;\n\n        }\n        try {\n            Structure.FieldOrder fieldOrder = inst.getClass().getAnnotation(Structure.FieldOrder.class);\n            if (fieldOrder != null) {\n                fields = Arrays.asList(fieldOrder.value());\n            } else {\n                Method getFieldOrder = inst.getClass().getDeclaredMethod(\"getFieldOrder\");\n                getFieldOrder.setAccessible(true);\n                fields = (List<String>) getFieldOrder.invoke(inst);\n            }\n        } catch (Exception ex) {\n            LOG.log(Level.SEVERE, \"Can't find getFieldOrder() method\", ex);\n            assertTrue(false);\n        }\n        testFields(inst, fields);\n    }\n\n    private void testFields(Structure inst, List<String> expectedFields) {\n        Field[] fields = inst.getClass().getFields();\n        List<String> fieldNames = new ArrayList<String>();\n        for (Field field : fields) {\n            if (!Modifier.isStatic(field.getModifiers())) {\n                fieldNames.add(field.getName());\n            }\n        }\n        assertTrue(expectedFields.equals(fieldNames));\n    }\n\n    private static void initStructList() {\n        structs = new ArrayList<>();\n\n        structs.add(BaseSinkAPI.GstBaseSinkStruct.class);\n        structs.add(BaseSinkAPI.GstBaseSinkClass.class);\n\n        structs.add(BaseSrcAPI.GstBaseSrcStruct.class);\n        structs.add(BaseSrcAPI.GstBaseSrcAbi.class);\n        structs.add(BaseSrcAPI.GstBaseSrcClass.class);\n\n        structs.add(BaseTransformAPI.GstBaseTransformStruct.class);\n        structs.add(BaseTransformAPI.GstBaseTransformClass.class);\n\n        structs.add(GObjectAPI.GTypeClass.class);\n        structs.add(GObjectAPI.GTypeInstance.class);\n        structs.add(GObjectAPI.GObjectStruct.class);\n        structs.add(GObjectAPI.GObjectClass.class);\n        structs.add(GObjectAPI.GTypeInfo.class);\n        structs.add(GObjectAPI.GParamSpec.class);\n        structs.add(GObjectAPI.GParamSpecBoolean.class);\n        structs.add(GObjectAPI.GParamSpecChar.class);\n        structs.add(GObjectAPI.GParamSpecDouble.class);\n        structs.add(GObjectAPI.GParamSpecFloat.class);\n        structs.add(GObjectAPI.GParamSpecInt.class);\n        structs.add(GObjectAPI.GParamSpecInt64.class);\n        structs.add(GObjectAPI.GParamSpecLong.class);\n        structs.add(GObjectAPI.GParamSpecString.class);\n        structs.add(GObjectAPI.GParamSpecUChar.class);\n        structs.add(GObjectAPI.GParamSpecUInt.class);\n\n        structs.add(GSignalAPI.GSignalQuery.class);\n\n        structs.add(GValueAPI.GValue.class);\n        structs.add(GValueAPI.GValueArray.class);\n\n        structs.add(GValueStruct.class);\n\n        structs.add(GlibAPI.GList.class);\n        structs.add(GlibAPI.GSList.class);\n\n        structs.add(GstAPI.GstSegmentStruct.class);\n        structs.add(GstAPI.GErrorStruct.class);\n\n        structs.add(GstBufferAPI.BufferStruct.class);\n\n        structs.add(GstColorBalanceAPI.ColorBalanceChannelStruct.class);\n\n//        structs.add(GstControlSourceAPI.TimedValue.class);\n//        structs.add(GstControlSourceAPI.GstControlSourceStruct.class);\n//        structs.add(GstControlSourceAPI.GstControlSourceClass.class);\n\n        structs.add(GstElementAPI.GstElementStruct.class);\n        structs.add(GstElementAPI.GstElementClass.class);\n\n        structs.add(GstEventAPI.EventStruct.class);\n        structs.add(GstVideoAPI.GstVideoTimeCodeMetaStruct.class);\n        structs.add(GstVideoAPI.GstVideoTimeCodeStruct.class);\n        structs.add(GstMetaAPI.GstMetaInfoStruct.class);\n        structs.add(GstMetaAPI.GstMetaStruct.class);\n\n//        structs.add(GstInterpolationControlSourceAPI.GstInterpolationControlSourceStruct.class);\n//        structs.add(GstInterpolationControlSourceAPI.GstInterpolationControlSourceClass.class);\n//\n//        structs.add(GstLFOControlSourceAPI.GstLFOControlSourceStruct.class);\n//        structs.add(GstLFOControlSourceAPI.GstLFOControlSourceClass.class);\n\n        structs.add(GstMessageAPI.MessageStruct.class);\n\n        structs.add(GstMiniObjectAPI.MiniObjectStruct.class);\n\n        structs.add(GstObjectAPI.GstObjectStruct.class);\n        structs.add(GstObjectAPI.GstObjectClass.class);\n\n        structs.add(GstQueryAPI.QueryStruct.class);\n\n        if (Gst.getVersion().getMinor() >= 14) {\n            structs.add(GstWebRTCSessionDescriptionAPI.WebRTCSessionDescriptionStruct.class);\n            structs.add(GstSDPMessageAPI.SDPMessageStruct.class);\n            structs.add(GstPromiseAPI.PromiseStruct.class);\n        }\n\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/lowlevel/ReferenceManagerTest.java",
    "content": "/* \n * Copyright (c) 2008 Wayne Meissner\n * \n * This file is part of gstreamer-java.\n *\n * gstreamer-java is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * gstreamer-java is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with gstreamer-java.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.freedesktop.gstreamer.lowlevel;\n\nimport org.freedesktop.gstreamer.lowlevel.ReferenceManager;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertTrue;\n\nimport java.lang.ref.Reference;\nimport java.lang.ref.WeakReference;\n\nimport org.freedesktop.gstreamer.Caps;\nimport org.freedesktop.gstreamer.Gst;\nimport org.junit.After;\nimport org.junit.AfterClass;\nimport org.junit.Before;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\n/**\n *\n */\npublic class ReferenceManagerTest {\n\n    public ReferenceManagerTest() {\n    }\n\n    @BeforeClass\n    public static void setUpClass() throws Exception {\n        Gst.init(\"ReferenceManagerTest\", new String[] {});\n    }\n    \n    @AfterClass\n    public static void tearDownClass() throws Exception {\n        Gst.deinit();\n    }\n\n    @Before\n    public void setUp() {\n    }\n\n    @After\n    public void tearDown() {\n    }\n    public boolean waitGC(Reference<? extends Object> ref) throws InterruptedException {\n        System.gc();\n        for (int i = 0; ref.get() != null && i < 20; ++i) {\n            Thread.sleep(10);\n            System.gc();\n        }\n        return ref.get() == null;\n    }\n\n    @Test public void testReference() throws Exception {\n        Object ref = new Object();\n        Caps target = new Caps(\"video/x-raw\");\n        ReferenceManager.addKeepAliveReference(ref, target);\n        WeakReference<Object> targetRef = new WeakReference<Object>(target);\n        target = null;\n        assertFalse(\"target collected prematurely\", waitGC(targetRef));\n        ref = null;\n        assertTrue(\"target not collected when ref is collected\", waitGC(targetRef));\n    }\n    @Test public void testMultipleReferences() throws Exception {\n        Object ref1 = new Object();\n        Object ref2 = new Object();\n        Caps target = new Caps(\"video/x-raw\");\n        ReferenceManager.addKeepAliveReference(ref1, target);\n        ReferenceManager.addKeepAliveReference(ref2, target);\n        WeakReference<Object> targetRef = new WeakReference<Object>(target);\n        target = null;\n        assertFalse(\"target collected prematurely\", waitGC(targetRef));\n        ref1 = null;\n        assertFalse(\"target collected after only one ref disposed\", waitGC(targetRef));\n        ref2 = null;\n        assertTrue(\"target not collected when ref is dispose\", waitGC(targetRef));\n    }\n}"
  },
  {
    "path": "test/org/freedesktop/gstreamer/util/TestAssumptions.java",
    "content": "package org.freedesktop.gstreamer.util;\n\nimport org.freedesktop.gstreamer.ElementFactory;\nimport org.freedesktop.gstreamer.Gst;\nimport org.junit.Assume;\n\n/**\n * These Assumptions skip Tests if the environmental Properties do not meet the Assumption.\n */\npublic class TestAssumptions {\n    /**\n     * Assume a GStreamer-Installation of at least the specified Version, ignore the Test if not met.\n     *\n     * @param major Required Major Version\n     * @param minor Required Minor Version\n     */\n    public static void requireGstVersion(int major, int minor) {\n        Assume.assumeTrue(Gst.testVersion(major, minor));\n    }\n    \n    /**\n     * Assume a GStreamer installation has the required element.\n     * \n     * @param elementType element type\n     */\n    public static void requireElement(String elementType) {\n        ElementFactory factory = null;\n        try {\n            factory = ElementFactory.find(elementType);\n        } catch (Exception ex) {}\n        Assume.assumeNotNull(factory);\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/video/VideoCropMetaTest.java",
    "content": "/*\n * Copyright (c) 2020 Neil C Smith\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n *\n */\npackage org.freedesktop.gstreamer.video;\n\nimport org.freedesktop.gstreamer.BufferProbeTester;\nimport org.freedesktop.gstreamer.Gst;\nimport org.freedesktop.gstreamer.glib.Natives;\nimport org.freedesktop.gstreamer.lowlevel.GstMetaPtr;\nimport org.freedesktop.gstreamer.util.TestAssumptions;\nimport org.junit.AfterClass;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\n\n\npublic class VideoCropMetaTest {\n\n    @BeforeClass\n    public static void beforeClass() {\n        Gst.init(Gst.getVersion());\n    }\n\n    @AfterClass\n    public static void afterClass() {\n        Gst.deinit();\n    }\n\n    @Test\n    public void testIterateWithCrop() {\n        TestAssumptions.requireGstVersion(1, 14);\n        TestAssumptions.requireElement(\"fakevideosink\");\n        BufferProbeTester.test(buffer -> {\n            buffer.iterateMeta().forEachRemaining(meta -> {\n                GstMetaPtr ptr = Natives.getPointer(meta).as(GstMetaPtr.class, GstMetaPtr::new);\n                System.out.println(ptr.getGType().getTypeName());\n                System.out.println(ptr.getAPIGType().getTypeName());\n        });\n            \n        }, \"videotestsrc ! videocrop top=10 left=10 bottom=50 right=50 ! fakevideosink name=sink\");\n    }\n    \n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/video/VideoTimeCodeConfigTest.java",
    "content": "/*\n * Copyright (c) 2020 Petr Lastovka\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n *\n */\npackage org.freedesktop.gstreamer.video;\n\nimport org.freedesktop.gstreamer.glib.NativeFlags;\nimport org.junit.Before;\nimport org.junit.Test;\n\nimport static org.junit.Assert.assertEquals;\n\nimport org.freedesktop.gstreamer.lowlevel.GstVideoAPI;\n\npublic class VideoTimeCodeConfigTest {\n    private GstVideoAPI.GstVideoTimeCodeConfigStruct origStruct;\n    private VideoTimeCodeConfig codeConfig;\n\n\n    @Before\n    public void setUp() {\n        origStruct = new GstVideoAPI.GstVideoTimeCodeConfigStruct();\n        origStruct.fps_d = 25;\n        origStruct.fps_n = 1;\n        origStruct.flags = VideoTimeCodeFlags.GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME.intValue();\n        origStruct.write();\n\n        codeConfig = new VideoTimeCodeConfig(origStruct);\n    }\n\n    @Test\n    public void testGetTimeCodeFlags() {\n        assertEquals(origStruct.flags, NativeFlags.toInt(codeConfig.getFlags()));\n    }\n\n    @Test\n    public void testGetFramerateNumerator() {\n        assertEquals(origStruct.fps_n, codeConfig.getNumerator());\n    }\n\n    @Test\n    public void testGetFramerateDenominator() {\n        assertEquals(origStruct.fps_d, codeConfig.getDenominator());\n    }\n}"
  },
  {
    "path": "test/org/freedesktop/gstreamer/video/VideoTimeCodeFlagsTest.java",
    "content": "/*\n * Copyright (c) 2020 Petr Lastovka\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n *\n */\npackage org.freedesktop.gstreamer.video;\n\nimport java.util.Arrays;\nimport java.util.Collection;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.junit.runners.Parameterized;\n\nimport static org.junit.Assert.assertEquals;\n\n\n@RunWith(Parameterized.class)\npublic class VideoTimeCodeFlagsTest {\n\n    private final VideoTimeCodeFlags flags;\n    private final int intValue;\n\n    @Parameterized.Parameters\n    public static Collection<Object[]> data() {\n        return Arrays.asList(\n                new Object[][]{\n//                        {VideoTimeCodeFlags.GST_VIDEO_TIME_CODE_FLAGS_NONE, 0},\n                        {VideoTimeCodeFlags.GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 1},\n                        {VideoTimeCodeFlags.GST_VIDEO_TIME_CODE_FLAGS_INTERLACED, 2}\n                });\n    }\n\n    public VideoTimeCodeFlagsTest(VideoTimeCodeFlags flags, int intValue) {\n        this.flags = flags;\n        this.intValue = intValue;\n    }\n\n    @Test\n    public void testIntValue() {\n        assertEquals(intValue,flags.intValue());\n    }\n}"
  },
  {
    "path": "test/org/freedesktop/gstreamer/video/VideoTimeCodeMetaTest.java",
    "content": "/*\n * Copyright (c) 2025 Neil C Smith\n * Copyright (c) 2020 Petr Lastovka\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n *\n */\npackage org.freedesktop.gstreamer.video;\n\nimport org.freedesktop.gstreamer.Buffer;\nimport org.freedesktop.gstreamer.Gst;\nimport org.freedesktop.gstreamer.SampleTester;\nimport org.freedesktop.gstreamer.util.TestAssumptions;\nimport org.junit.AfterClass;\nimport org.junit.BeforeClass;\nimport org.junit.Test;\n\nimport static org.freedesktop.gstreamer.video.VideoTimeCodeFlags.GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME;\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertNotNull;\nimport static org.junit.Assert.assertTrue;\n\npublic class VideoTimeCodeMetaTest {\n\n    @BeforeClass\n    public static void beforeClass() {\n        Gst.init(Gst.getVersion());\n    }\n\n    @AfterClass\n    public static void afterClass() {\n        Gst.deinit();\n    }\n\n    @Test\n    public void testVideoWithoutTimeCodeMeta() {\n        // method containsMetadata is available since 1.14\n        TestAssumptions.requireGstVersion(1, 14);\n        SampleTester.test(sample -> {\n            Buffer buffer = sample.getBuffer();\n            assertFalse(\"Default video not contains timecode metadata\", buffer.hasMeta(VideoTimeCodeMeta.API));\n        }, \"videotestsrc do-timestamp=true ! appsink name=myappsink\");\n    }\n\n    @Test\n    public void testVideoTimeCodeMetaPal() {\n        // timecodestamper is available since 1.10\n        TestAssumptions.requireGstVersion(1, 10);\n        TestAssumptions.requireElement(\"timecodestamper\");\n        SampleTester.test(sample -> {\n            Buffer buffer = sample.getBuffer();\n            if (Gst.testVersion(1, 14)) {\n                assertTrue(\"Video should contains timecode meta\", buffer.hasMeta(VideoTimeCodeMeta.API));\n            }\n            try (VideoTimeCodeMeta meta = buffer.getMeta(VideoTimeCodeMeta.API)) {\n                assertNotNull(meta);\n                VideoTimeCode timeCode = meta.getTimeCode();\n\n                //first frame 00:00:00:00\n                assertEquals(0, timeCode.getHours());\n                assertEquals(0, timeCode.getMinutes());\n                assertEquals(0, timeCode.getSeconds());\n                assertEquals(0, timeCode.getFrames());\n\n                VideoTimeCodeConfig timeCodeConfig = timeCode.getConfig();\n                // PAL standard 25/1\n                assertEquals(25, timeCodeConfig.getNumerator());\n                assertEquals(1, timeCodeConfig.getDenominator());\n                assertTrue(timeCodeConfig.getFlags().isEmpty());\n            }\n        }, \"videotestsrc ! video/x-raw,framerate=25/1 ! timecodestamper ! videoconvert ! appsink name=myappsink\");\n    }\n\n    @Test\n    public void testVideoTimeCodeNTSCDrop() {\n        // timecodestamper is available since 1.10\n        TestAssumptions.requireGstVersion(1, 10);\n        TestAssumptions.requireElement(\"timecodestamper\");\n        SampleTester.test(sample -> {\n            Buffer buffer = sample.getBuffer();\n            if (Gst.testVersion(1, 14)) {\n                assertTrue(\"Video should contains timecode meta\", buffer.hasMeta(VideoTimeCodeMeta.API));\n            }\n            try (VideoTimeCodeMeta meta = buffer.getMeta(VideoTimeCodeMeta.API)) {\n                assertNotNull(meta);\n                VideoTimeCode timeCode = meta.getTimeCode();\n\n                //first frame 00:00:00;00\n                assertEquals(0, timeCode.getHours());\n                assertEquals(0, timeCode.getMinutes());\n                assertEquals(0, timeCode.getSeconds());\n                assertEquals(0, timeCode.getFrames());\n\n                VideoTimeCodeConfig timeCodeConfig = timeCode.getConfig();\n                // NTSC drop standard 30000/1001\n                assertEquals(30000, timeCodeConfig.getNumerator());\n                assertEquals(1001, timeCodeConfig.getDenominator());\n                assertTrue(timeCodeConfig.getFlags().contains(GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME));\n            }\n        }, \"videotestsrc ! video/x-raw,framerate=30000/1001 ! timecodestamper drop-frame=true ! videoconvert ! appsink name=myappsink\");\n    }\n\n    /**\n     * Handle last frame of first minute\n     */\n    @Test\n    public void testVideoTimeCodeNTSCDropFrame() {\n        // timecodestamper is available since 1.10\n        TestAssumptions.requireGstVersion(1, 10);\n        TestAssumptions.requireElement(\"timecodestamper\");\n        SampleTester.test(sample -> {\n            Buffer buffer = sample.getBuffer();\n            if (Gst.testVersion(1, 14)) {\n                assertTrue(\"Video should contains timecode meta\", buffer.hasMeta(VideoTimeCodeMeta.API));\n            }\n            try (VideoTimeCodeMeta meta = buffer.getMeta(VideoTimeCodeMeta.API)) {\n                assertNotNull(meta);\n                VideoTimeCode timeCode = meta.getTimeCode();\n\n                //first frame 00:00:00;29\n                assertEquals(0, timeCode.getHours());\n                assertEquals(0, timeCode.getMinutes());\n                assertEquals(0, timeCode.getSeconds());\n                assertEquals(29, timeCode.getFrames());\n\n                VideoTimeCodeConfig timeCodeConfig = timeCode.getConfig();\n                // NTSC drop standard 30000/1001\n                assertEquals(30000, timeCodeConfig.getNumerator());\n                assertEquals(1001, timeCodeConfig.getDenominator());\n                assertTrue(timeCodeConfig.getFlags().contains(GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME));\n            }\n        }, \"videotestsrc ! video/x-raw,framerate=30000/1001 ! videoconvert ! timecodestamper drop-frame=true ! videoconvert ! appsink name=myappsink\", 29);\n    }\n\n    @Test\n    public void testVideoTimeCodeNTSCNonDrop() {\n        // timecodestamper is available since 1.10\n        TestAssumptions.requireGstVersion(1, 10);\n        TestAssumptions.requireElement(\"timecodestamper\");\n        SampleTester.test(sample -> {\n            Buffer buffer = sample.getBuffer();\n            if (Gst.testVersion(1, 14)) {\n                assertTrue(\"Video should contains timecode meta\", buffer.hasMeta(VideoTimeCodeMeta.API));\n            }\n            try (VideoTimeCodeMeta meta = buffer.getMeta(VideoTimeCodeMeta.API)) {\n                assertNotNull(meta);\n                VideoTimeCode timeCode = meta.getTimeCode();\n\n                //first frame 00:00:00:00\n                assertEquals(0, timeCode.getHours());\n                assertEquals(0, timeCode.getMinutes());\n                assertEquals(0, timeCode.getSeconds());\n                assertEquals(0, timeCode.getFrames());\n\n                VideoTimeCodeConfig timeCodeConfig = timeCode.getConfig();\n                // NTSC drop standard 30/1\n                assertEquals(30, timeCodeConfig.getNumerator());\n                assertEquals(1, timeCodeConfig.getDenominator());\n                assertTrue(timeCodeConfig.getFlags().isEmpty());\n            }\n        }, \"videotestsrc ! video/x-raw,framerate=30/1 ! timecodestamper ! videoconvert ! appsink name=myappsink\");\n    }\n}\n"
  },
  {
    "path": "test/org/freedesktop/gstreamer/video/VideoTimeCodeTest.java",
    "content": "/*\n * Copyright (c) 2020 Neil C Smith\n * Copyright (c) 2020 Petr Lastovka\n *\n * This file is part of gstreamer-java.\n *\n * This code is free software: you can redistribute it and/or modify it under\n * the terms of the GNU Lesser General Public License version 3 only, as\n * published by the Free Software Foundation.\n *\n * This code is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\n * version 3 for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.\n *\n */\npackage org.freedesktop.gstreamer.video;\n\nimport org.junit.Before;\nimport org.junit.Test;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertNotNull;\n\nimport org.freedesktop.gstreamer.lowlevel.GstVideoAPI;\n\n\npublic class VideoTimeCodeTest {\n\n\n    private GstVideoAPI.GstVideoTimeCodeStruct timeCodeStruct;\n    private GstVideoAPI.GstVideoTimeCodeConfigStruct.ByValue configStruct;\n\n    private VideoTimeCode timeCode;\n\n    @Before\n    public void setUp() {\n        timeCodeStruct = new GstVideoAPI.GstVideoTimeCodeStruct();\n        configStruct = new GstVideoAPI.GstVideoTimeCodeConfigStruct.ByValue();\n\n        // 01:02:03:04\n        timeCodeStruct.hours = 1;\n        timeCodeStruct.minutes = 2;\n        timeCodeStruct.seconds = 3;\n        timeCodeStruct.frames = 4;\n\n        timeCodeStruct.field_count = 55;\n\n        // config\n        timeCodeStruct.config = configStruct;\n\n        timeCodeStruct.write();\n        timeCode = new VideoTimeCode(timeCodeStruct);\n\n\n    }\n\n    @Test\n    public void testGetTCConfig() {\n        assertNotNull(timeCode.getConfig());\n    }\n\n    @Test\n    public void testGetHours() {\n        assertEquals(1,timeCode.getHours());\n    }\n\n    @Test\n    public void testGetMinutes() {\n        assertEquals(2,timeCode.getMinutes());\n    }\n\n    @Test\n    public void testGetSeconds() {\n        assertEquals(3,timeCode.getSeconds());\n    }\n\n    @Test\n    public void testGetFrames() {\n        assertEquals(4,timeCode.getFrames());\n    }\n}\n"
  }
]