1 /* 2 * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.media.jfxmediaimpl.platform.gstreamer; 27 28 import com.sun.media.jfxmedia.Media; 29 import com.sun.media.jfxmedia.MediaError; 30 import com.sun.media.jfxmedia.MediaPlayer; 31 import com.sun.media.jfxmedia.events.PlayerStateEvent.PlayerState; 32 import com.sun.media.jfxmedia.locator.Locator; 33 import com.sun.media.jfxmedia.logging.Logger; 34 import com.sun.media.jfxmediaimpl.HostUtils; 35 import com.sun.media.jfxmediaimpl.MediaUtils; 36 import com.sun.media.jfxmediaimpl.platform.Platform; 37 import java.util.Arrays; 38 39 /** 40 * GStreamer platform implementation. 41 */ 42 public final class GSTPlatform extends Platform { 43 /** 44 * The MIME types of all supported media. 45 */ 46 private static final String[] CONTENT_TYPES = { 47 "audio/x-aiff", 48 "audio/mp3", 49 "audio/mpeg", 50 "audio/x-wav", 51 "video/x-javafx", 52 "video/x-flv", 53 "video/x-fxm", 54 "video/mp4", 55 "audio/x-m4a", 56 "video/x-m4v", 57 "application/vnd.apple.mpegurl", 58 "audio/mpegurl" 59 }; 60 61 /** 62 * All supported protocols. 63 */ 64 private static final String[] PROTOCOLS = { 65 "file", 66 "http", 67 "https" 68 }; 69 70 private static GSTPlatform globalInstance = null; 71 72 @Override 73 public boolean loadPlatform() { 74 // Initialize GStreamer JNI and supporting native classes. 75 MediaError ret; 76 try { 77 ret = MediaError.getFromCode(gstInitPlatform()); 78 } catch (UnsatisfiedLinkError ule) { 79 ret = MediaError.ERROR_MANAGER_ENGINEINIT_FAIL; 80 } 81 // Post an error if native initialization fails. 82 if (ret != MediaError.ERROR_NONE) { 83 MediaUtils.nativeError(GSTPlatform.class, ret); 84 } 85 return true; 86 } 87 88 /* 89 * Get an instance of the platform. 90 */ 91 public static synchronized Platform getPlatformInstance() { 92 if (null == globalInstance) { 93 globalInstance = new GSTPlatform(); 94 } 95 96 return globalInstance; 97 } 98 99 private GSTPlatform() {} 100 101 @Override 102 public String[] getSupportedContentTypes() { 103 return Arrays.copyOf(CONTENT_TYPES, CONTENT_TYPES.length); 104 } 105 106 @Override 107 public String[] getSupportedProtocols() { 108 return Arrays.copyOf(PROTOCOLS, PROTOCOLS.length); 109 } 110 111 @Override 112 public Media createMedia(Locator source) { 113 return new GSTMedia(source); 114 } 115 116 @Override 117 public MediaPlayer createMediaPlayer(Locator source) { 118 GSTMediaPlayer player; 119 try { 120 player = new GSTMediaPlayer(source); 121 } catch (Exception e) { 122 if (Logger.canLog(Logger.DEBUG)) { 123 Logger.logMsg(Logger.DEBUG, "GSTPlatform caught exception while creating media player: "+e); 124 } 125 return null; 126 } 127 128 // Special case for H.264 decoding on Mac OS X. 129 if (HostUtils.isMacOSX()) { 130 String contentType = source.getContentType(); 131 if ("video/mp4".equals(contentType) || "video/x-m4v".equals(contentType) 132 || source.getStringLocation().endsWith(".m3u8")) 133 { 134 // Block until player transitions to READY or HALTED. 135 136 // Timeouts in milliseconds. 137 String scheme = source.getURI().getScheme(); 138 final long timeout = (scheme.equals("http") || scheme.equals("https")) ? 139 60000L : 5000L; 140 final long iterationTime = 50L; 141 long timeWaited = 0L; 142 143 final Object lock = new Object(); 144 PlayerState state = player.getState(); 145 146 while (timeWaited < timeout && 147 (state == PlayerState.UNKNOWN || state == PlayerState.STALLED)) { 148 try { 149 synchronized(lock) { 150 lock.wait(iterationTime); 151 timeWaited += iterationTime; 152 } 153 } catch (InterruptedException ex) { 154 // Ignore it. 155 } 156 157 state = player.getState(); 158 } 159 160 // If the player is not READY, an error occurred. 161 if (player.getState() != PlayerState.READY) { 162 player.dispose(); 163 player = null; 164 } 165 } 166 } 167 return player; 168 } 169 170 /** 171 * Initialize the native peer of this media manager. 172 * 173 * @return A status code. 174 */ 175 private static native int gstInitPlatform(); 176 }