11/*
2+ * Copyright (c) 2019 Neil C Smith
23 * Copyright (c) 2018 Antonio Morales
3- * Copyright (c) 2018 Neil C Smith
44 * Copyright (c) 2007 Wayne Meissner
55 *
66 * This file is part of gstreamer-java.
6060import com .sun .jna .Pointer ;
6161import com .sun .jna .ptr .IntByReference ;
6262import com .sun .jna .ptr .PointerByReference ;
63+ import java .lang .annotation .Documented ;
64+ import java .lang .annotation .Retention ;
65+ import java .lang .annotation .RetentionPolicy ;
6366import java .util .Arrays ;
6467import java .util .logging .Level ;
6568import static org .freedesktop .gstreamer .lowlevel .GstParseAPI .GSTPARSE_API ;
7073 */
7174@ SuppressWarnings ("deprecation" )
7275public final class Gst {
73- private static Logger logger = Logger .getLogger (Gst .class .getName ());
76+
77+ private final static Logger LOG = Logger .getLogger (Gst .class .getName ());
78+ private final static AtomicInteger INIT_COUNT = new AtomicInteger (0 );
79+ private final static boolean CHECK_VERSIONS = !Boolean .getBoolean ("gstreamer.suppressVersionChecks" );
80+
7481
7582 private static ScheduledExecutorService executorService ;
7683 private static volatile CountDownLatch quit = new CountDownLatch (1 );
7784 private static GMainContext mainContext ;
7885 private static boolean useDefaultContext = false ;
79- private static final AtomicInteger initCount = new AtomicInteger (0 );
80- private static List <Runnable > shutdownTasks = Collections .synchronizedList (new ArrayList <Runnable >());
86+ private static List <Runnable > shutdownTasks = Collections .synchronizedList (new ArrayList <Runnable >());
87+ // set minorVersion to a value guaranteed to be >= anything else unless set in init()
88+ private static int minorVersion = Integer .MAX_VALUE ;
8189
8290 public static class NativeArgs {
8391 public IntByReference argcRef ;
@@ -135,7 +143,7 @@ private Gst() {
135143 public static Version getVersion () {
136144 long [] major = { 0 }, minor = { 0 }, micro = { 0 }, nano = { 0 };
137145 GST_API .gst_version (major , minor , micro , nano );
138- return new Version (major [0 ], minor [0 ], micro [0 ], nano [0 ]);
146+ return new Version (( int ) major [0 ], ( int ) minor [0 ], ( int ) micro [0 ], ( int ) nano [0 ]);
139147 }
140148
141149 /**
@@ -167,7 +175,7 @@ public static void setSegTrap(boolean enabled) {
167175 * @return true if the GStreamer library already initialized.
168176 */
169177 public static synchronized final boolean isInitialized () {
170- return initCount .get () > 0 ;
178+ return INIT_COUNT .get () > 0 ;
171179 }
172180
173181 /**
@@ -234,7 +242,7 @@ public static Element parseLaunch(String pipelineDescription, List<GError> error
234242 if (errors != null ) {
235243 errors .add (new GError (new GErrorStruct (err [0 ])));
236244 } else {
237- logger .log (Level .WARNING , new GError (new GErrorStruct (err [0 ])).getMessage ());
245+ LOG .log (Level .WARNING , new GError (new GErrorStruct (err [0 ])).getMessage ());
238246 }
239247 }
240248
@@ -283,7 +291,7 @@ public static Element parseLaunch(String[] pipelineDescription, List<GError> err
283291 if (errors != null ) {
284292 errors .add (new GError (new GErrorStruct (err [0 ])));
285293 } else {
286- logger .log (Level .WARNING , new GError (new GErrorStruct (err [0 ])).getMessage ());
294+ LOG .log (Level .WARNING , new GError (new GErrorStruct (err [0 ])).getMessage ());
287295 }
288296 }
289297
@@ -330,7 +338,7 @@ public static Bin parseBinFromDescription(String binDescription, boolean ghostUn
330338 if (errors != null ) {
331339 errors .add (new GError (new GErrorStruct (err [0 ])));
332340 } else {
333- logger .log (Level .WARNING , new GError (new GErrorStruct (err [0 ])).getMessage ());
341+ LOG .log (Level .WARNING , new GError (new GErrorStruct (err [0 ])).getMessage ());
334342 }
335343 }
336344
@@ -411,8 +419,46 @@ public static GMainContext getMainContext() {
411419 *
412420 * @throws org.freedesktop.gstreamer.GstException
413421 */
422+ @ Deprecated
414423 public static final void init () throws GstException {
415- init ("unknown" , new String [] {});
424+ init (new Version (1 , 8 ), "gst1-java-core" );
425+ }
426+
427+ /**
428+ * Initializes the GStreamer library.
429+ * <p> This is a shortcut if no arguments are to be passed to gstreamer.
430+ *
431+ * @param requiredVersion
432+ * @throws org.freedesktop.gstreamer.GstException
433+ */
434+ public static final void init (Version requiredVersion ) throws GstException {
435+ init (requiredVersion , "gst1-java-core" );
436+ }
437+
438+
439+ /**
440+ * Initializes the GStreamer library.
441+ * <p> This sets up internal path lists, registers built-in elements, and
442+ * loads standard plugins.
443+ *
444+ * <p>
445+ * This method should be called before calling any other GLib functions. If
446+ * this is not an option, your program must initialise the GLib thread system
447+ * using g_thread_init() before any other GLib functions are called.
448+ *
449+ * <p>
450+ * <b>Note:</b><p>
451+ * This method will throw a GstException if it fails.
452+ *
453+ * @param progname the java program name.
454+ * @param args the java argument list.
455+ * @return the list of arguments with any gstreamer specific options stripped
456+ * out.
457+ * @throws org.freedesktop.gstreamer.GstException
458+ */
459+ @ Deprecated
460+ public static synchronized final String [] init (String progname , String ... args ) throws GstException {
461+ return init (new Version (1 , 8 ), progname , args );
416462 }
417463
418464 /**
@@ -429,29 +475,58 @@ public static final void init() throws GstException {
429475 * <b>Note:</b><p>
430476 * This method will throw a GstException if it fails.
431477 *
478+ * @param requestedVersion the minimum requested GStreamer version.
432479 * @param progname the java program name.
433480 * @param args the java argument list.
434481 * @return the list of arguments with any gstreamer specific options stripped
435482 * out.
436483 * @throws org.freedesktop.gstreamer.GstException
437484 */
438- public static synchronized final String [] init (String progname , String [] args ) throws GstException {
485+ public static synchronized final String [] init (Version requestedVersion ,
486+ String progname , String ... args ) throws GstException {
487+
488+ if (CHECK_VERSIONS ) {
489+ Version availableVersion = getVersion ();
490+ if (requestedVersion .getMajor () != 1 || availableVersion .getMajor () != 1 ) {
491+ throw new GstException ("gst1-java-core only supports GStreamer 1.x" );
492+ }
493+ if (requestedVersion .getMinor () < 8 ) {
494+ requestedVersion = new Version (1 , 8 );
495+ }
496+ if (!availableVersion .checkSatisfies (requestedVersion )) {
497+ throw new GstException (String .format (
498+ "The requested version of GStreamer is not available\n Requested : %s\n Available : %s\n " ,
499+ requestedVersion , availableVersion ));
500+ }
501+ }
502+
439503 //
440504 // Only do real init the first time through
441505 //
442- if (initCount .getAndIncrement () > 0 ) {
506+ if (INIT_COUNT .getAndIncrement () > 0 ) {
507+ if (CHECK_VERSIONS ) {
508+ if (requestedVersion .getMinor () > minorVersion ) {
509+ minorVersion = (int ) requestedVersion .getMinor ();
510+ }
511+ }
443512 return args ;
444513 }
514+
445515 NativeArgs argv = new NativeArgs (progname , args );
446516
447517 Pointer [] error = { null };
448518 if (!GST_API .gst_init_check (argv .argcRef , argv .argvRef , error )) {
449- initCount .decrementAndGet ();
519+ INIT_COUNT .decrementAndGet ();
450520 throw new GstException (new GError (new GErrorStruct (error [0 ])));
451521 }
452522
453- logger .fine ("after gst_init, argc=" + argv .argcRef .getValue ());
454-
523+ LOG .fine ("after gst_init, argc=" + argv .argcRef .getValue ());
524+
525+ Version runningVersion = getVersion ();
526+ if (runningVersion .getMajor () != 1 ) {
527+ LOG .warning ("gst1-java-core only supports GStreamer 1.x" );
528+ }
529+
455530 if (useDefaultContext ) {
456531 mainContext = GMainContext .getDefaultContext ();
457532 executorService = new MainContextExecutorService (mainContext );
@@ -461,6 +536,11 @@ public static synchronized final String[] init(String progname, String[] args) t
461536 }
462537 quit = new CountDownLatch (1 );
463538 loadAllClasses ();
539+
540+ if (CHECK_VERSIONS ) {
541+ minorVersion = requestedVersion .getMinor ();
542+ }
543+
464544 return argv .toStringArray ();
465545 }
466546
@@ -473,7 +553,7 @@ public static synchronized final void deinit() {
473553 //
474554 // Only perform real shutdown if called as many times as Gst.init() is
475555 //
476- if (initCount .decrementAndGet () > 0 ) {
556+ if (INIT_COUNT .decrementAndGet () > 0 ) {
477557 return ;
478558 }
479559 // Perform any cleanup tasks
@@ -527,6 +607,36 @@ public static void setUseDefaultContext(boolean useDefault) {
527607 useDefaultContext = useDefault ;
528608 }
529609
610+ /**
611+ * Checks that the version of GStreamer requested in init() satisfies the
612+ * given version or throws an exception.
613+ *
614+ * @param major major version, only 1 is supported
615+ * @param minor minor version required
616+ * @throws GstException if the requested version support was not requested
617+ */
618+ public static void checkVersion (int major , int minor ) {
619+ if (CHECK_VERSIONS && (major != 1 || minor > minorVersion )) {
620+ throw new GstException ("Not supported by requested GStreamer version" );
621+ }
622+ }
623+
624+ /**
625+ * Tests that the version of GStreamer requested in init() satisfies the
626+ * given version.
627+ *
628+ * @param major major version, only 1 is supported
629+ * @param minor minor version required
630+ * @return boolean whether the version requirement can be satisfied
631+ */
632+ public static boolean testVersion (int major , int minor ) {
633+ if (CHECK_VERSIONS && (major != 1 || minor > minorVersion )) {
634+ return false ;
635+ }
636+ return true ;
637+ }
638+
639+
530640 // Make the gstreamer executor threads daemon, so they don't stop the main
531641 // program from exiting
532642 private static final ThreadFactory threadFactory = new ThreadFactory () {
@@ -640,4 +750,18 @@ private static synchronized void loadAllClasses() {
640750 URIDecodeBin .class ,
641751 WebRTCBin .class
642752 );
753+
754+ /**
755+ * Annotation on classes, methods or fields to show the required GStreamer
756+ * version. This should particularly be used where the version required is higher
757+ * than the current baseline supported version (GStreamer 1.8)
758+ */
759+ @ Retention (RetentionPolicy .RUNTIME )
760+ @ Documented
761+ public static @interface Since {
762+ public int major () default 1 ;
763+ public int minor ();
764+ }
765+
766+
643767}
0 commit comments