1 /* 2 * Copyright (c) 2010, 2014, 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 38 /** 39 * GStreamer platform implementation. 40 */ 41 public final class GSTPlatform extends Platform { 42 /** 43 * The MIME types of all supported media. 44 */ 45 private static final String[] CONTENT_TYPES = { 46 "audio/x-aiff", 47 "audio/mp3", 48 "audio/mpeg", 49 "audio/x-wav", 50 "video/x-javafx", 51 "video/x-flv", 52 "video/x-fxm", 53 "video/mp4", 54 "audio/x-m4a", 55 "video/x-m4v", 56 "application/vnd.apple.mpegurl", 57 "audio/mpegurl" 58 }; 59 60 private static GSTPlatform globalInstance = null; 61 62 // HACK: move this back to native when we fix the jdeveloper crash 63 private static final String[] contentTypes; 64 65 static { 66 // HACK: remove this when we go back to polling native 67 if (!HostUtils.isMacOSX()) { 68 contentTypes = new String[CONTENT_TYPES.length]; 69 System.arraycopy(CONTENT_TYPES, 0, contentTypes, 70 0, CONTENT_TYPES.length); 71 } else { 72 contentTypes = CONTENT_TYPES; 73 } 74 } 75 76 @Override 77 public boolean loadPlatform() { 78 // Initialize GStreamer JNI and supporting native classes. 79 MediaError ret; 80 try { 81 ret = MediaError.getFromCode(gstInitPlatform()); 82 } catch (UnsatisfiedLinkError ule) { 83 ret = MediaError.ERROR_MANAGER_ENGINEINIT_FAIL; 84 } 85 // Post an error if native initialization fails. 86 if (ret != MediaError.ERROR_NONE) { 87 MediaUtils.nativeError(GSTPlatform.class, ret); 88 } 89 return true; 90 } 91 92 /* 93 * Get an instance of the platform. 94 */ 95 public static synchronized Platform getPlatformInstance() { 96 if (null == globalInstance) { 97 globalInstance = new GSTPlatform(); 98 } 99 100 return globalInstance; 101 } 102 103 private GSTPlatform() {} 104 105 @Override 106 public String[] getSupportedContentTypes() { 107 String[] contentTypesCopy = new String[contentTypes.length]; 108 System.arraycopy(contentTypes, 0, contentTypesCopy, 0, contentTypes.length); 109 return contentTypesCopy; 110 } 111 112 @Override 113 public Media createMedia(Locator source) { 114 return new GSTMedia(source); 115 } 116 117 @Override 118 public MediaPlayer createMediaPlayer(Locator source) { 119 GSTMediaPlayer player; 120 try { 121 player = new GSTMediaPlayer(source); 122 } catch (Exception e) { 123 if (Logger.canLog(Logger.DEBUG)) { 124 Logger.logMsg(Logger.DEBUG, "GSTPlatform caught exception while creating media player: "+e); 125 } 126 return null; 127 } 128 129 // Special case for H.264 decoding on Mac OS X. 130 if (HostUtils.isMacOSX()) { 131 String contentType = source.getContentType(); 132 if ("video/mp4".equals(contentType) || "video/x-m4v".equals(contentType) 133 || source.getStringLocation().endsWith(".m3u8")) 134 { 135 // Block until player transitions to READY or HALTED. 136 137 // Timeouts in milliseconds. 138 final long timeout = source.getURI().getScheme().equals("http") ? 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 } | 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 } |