1 /* 2 * Copyright (c) 2010, 2016, 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 #import "OSXMediaPlayer.h" 27 #import "OSXPlayerProtocol.h" 28 #import "com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer.h" 29 #import <Utils/JObjectPeers.h> 30 #import <Utils/JavaUtils.h> 31 #import <CoreAudio/CoreAudio.h> 32 #import <jni/Logger.h> 33 #import <jni/JniUtils.h> 34 #import <jfxmedia_errors.h> 35 36 #import <objc/runtime.h> 37 38 #define USE_WEAK_REFS 0 39 40 // Don't access directly, use the OSXMediaPlayer static methods to ensure thread safe access 41 static JObjectPeers *gMediaPlayerPeers = nil; 42 static Class gMediaPlayerClass = nil; 43 44 @implementation OSXMediaPlayer 45 46 + (void) initialize 47 { 48 gMediaPlayerPeers = [[JObjectPeers alloc] init]; 49 } 50 51 + (OSXMediaPlayer*) peerForPlayer:(jobject)javaPlayer andEnv:(JNIEnv*)javaEnv 52 { 53 return [gMediaPlayerPeers peerForJObject:javaPlayer javaEnv:javaEnv]; 54 } 55 56 + (void) setPeer:(OSXMediaPlayer*)player forJavaPlayer:(jobject)javaPlayer andEnv:(JNIEnv*)javaEnv 57 { 58 [gMediaPlayerPeers setPeer:player forJObject:javaPlayer javaEnv:javaEnv]; 59 } 60 61 + (void) removePlayerPeers:(OSXMediaPlayer*)player 62 { 63 [gMediaPlayerPeers removePeer:player]; 64 } 65 66 + (BOOL) initPlayerPlatform 67 { 68 BOOL enableAVF = YES; 69 BOOL enableQTK = YES; 70 71 // Check environment to see if platforms are enabled 72 char *value = getenv("JFXMEDIA_AVF"); 73 if (value ? strncasecmp(value, "yes", 3) != 0 : NO) { 74 enableAVF = NO; 75 } 76 77 value = getenv("JFXMEDIA_QTKIT"); 78 if (value ? strncasecmp(value, "yes", 3) != 0 : NO) { 79 enableQTK = NO; 80 } 81 82 // Determine if we can use OSX native player libs, without linking directly 83 Class klass; 84 85 if (enableAVF) { 86 klass = objc_getClass("AVFMediaPlayer"); 87 if (klass) { 88 if ([klass conformsToProtocol:@protocol(OSXPlayerProtocol)]) { 89 if ([klass respondsToSelector:@selector(playerAvailable)] ? [klass playerAvailable] : YES) { 90 gMediaPlayerClass = klass; 91 return YES; 92 } 93 } 94 } 95 } 96 97 if (enableQTK) { 98 klass = objc_getClass("QTKMediaPlayer"); 99 if (klass) { 100 // And make sure it conforms to the OSXPlayerProtocol 101 if ([klass conformsToProtocol:@protocol(OSXPlayerProtocol)]) { 102 if ([klass respondsToSelector:@selector(playerAvailable)] ? [klass playerAvailable] : YES) { 103 gMediaPlayerClass = klass; 104 return YES; 105 } 106 } 107 } 108 } 109 110 return NO; 111 } 112 113 - (id) init 114 { 115 if ((self = [super init]) != nil) { 116 } 117 return self; 118 } 119 120 - (id) initWithURL:(NSURL *)source javaPlayer:(jobject)jp andEnv:(JNIEnv*)env eventHandler:(CJavaPlayerEventDispatcher*)hdlr 121 { 122 if (!gMediaPlayerClass) { 123 // No player class available, abort 124 return nil; 125 } 126 127 if ((self = [super init]) != nil) { 128 movieURL = [source retain]; 129 130 env->GetJavaVM(&javaPlayerVM); 131 if (env->ExceptionCheck()) { 132 env->ExceptionClear(); 133 return nil; 134 } 135 #if USE_WEAK_REFS 136 javaPlayer = env->NewWeakGlobalRef(jp); 137 #else 138 javaPlayer = env->NewGlobalRef(jp); 139 #endif 140 // set up the peer association 141 [OSXMediaPlayer setPeer:self forJavaPlayer:javaPlayer andEnv:env]; 142 143 eventHandler = hdlr; 144 145 // create the player object 146 player = [[gMediaPlayerClass alloc] initWithURL:movieURL eventHandler:eventHandler]; 147 } 148 return self; 149 } 150 151 - (id) initWithURL:(NSURL *)source eventHandler:(CJavaPlayerEventDispatcher*)hdlr 152 { 153 // stub initWithURL message to satisfy the protocol requirements, this should 154 // never be called 155 return nil; 156 } 157 158 - (void) dealloc 159 { 160 [self dispose]; // just in case 161 [movieURL release]; 162 [super dealloc]; 163 } 164 165 - (void) dispose 166 { 167 @synchronized(self) { 168 [player dispose]; 169 [player release]; 170 player = nil; 171 172 if (eventHandler) { 173 eventHandler->Dispose(); 174 delete eventHandler; 175 } 176 eventHandler = NULL; 177 178 [OSXMediaPlayer removePlayerPeers:self]; 179 if (javaPlayerVM && javaPlayer) { 180 BOOL attached = NO; 181 JNIEnv *env = GetJavaEnvironment(javaPlayerVM, &attached); 182 183 // remove peer association 184 [OSXMediaPlayer removePlayerPeers:self]; 185 #if USE_WEAK_REFS 186 env->DeleteWeakGlobalRef(javaPlayer); 187 #else 188 env->DeleteGlobalRef(javaPlayer); 189 #endif 190 if (attached) { 191 javaPlayerVM->DetachCurrentThread(); 192 } 193 } 194 javaPlayer = 0; 195 javaPlayerVM = NULL; 196 } 197 } 198 199 - (id<OSXPlayerProtocol>) player 200 { 201 return [[player retain] autorelease]; 202 } 203 204 - (CAudioEqualizer*) audioEqualizer 205 { 206 return player.audioEqualizer; 207 } 208 209 - (CAudioSpectrum*) audioSpectrum 210 { 211 return player.audioSpectrum; 212 } 213 214 - (int64_t) audioSyncDelay 215 { 216 return player.audioSyncDelay; 217 } 218 219 - (void) setAudioSyncDelay:(int64_t)audioSyncDelay 220 { 221 player.audioSyncDelay = audioSyncDelay; 222 } 223 224 - (double) duration 225 { 226 return player.duration; 227 } 228 229 - (float) rate 230 { 231 return player.rate; 232 } 233 234 - (void) setRate:(float)rate 235 { 236 player.rate = rate; 237 } 238 239 - (double) currentTime 240 { 241 return player.currentTime; 242 } 243 244 - (void) setCurrentTime:(double)currentTime 245 { 246 player.currentTime = currentTime; 247 } 248 249 - (BOOL) mute 250 { 251 return player.mute; 252 } 253 254 - (void) setMute:(BOOL)mute 255 { 256 player.mute = mute; 257 } 258 259 - (float) volume 260 { 261 return player.volume; 262 } 263 264 - (void) setVolume:(float)volume 265 { 266 player.volume = volume; 267 } 268 269 - (float) balance 270 { 271 return player.balance; 272 } 273 274 - (void) setBalance:(float)balance 275 { 276 player.balance = balance; 277 } 278 279 - (void) play 280 { 281 [player play]; 282 } 283 284 - (void) pause 285 { 286 [player pause]; 287 } 288 289 - (void) finish 290 { 291 [player finish]; 292 } 293 294 - (void) stop 295 { 296 [player stop]; 297 } 298 299 @end 300 301 #pragma mark - 302 #pragma mark JNI Methods 303 304 /* 305 * Class: com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer 306 * Method: osxCreatePlayer 307 * Signature: (Ljava/lang/String;)V 308 */ 309 JNIEXPORT void JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxCreatePlayer 310 (JNIEnv *env, jobject playerObject, jstring sourceURI) 311 { 312 // create the event dispatcher, init later 313 CJavaPlayerEventDispatcher *eventHandler = new CJavaPlayerEventDispatcher(); 314 eventHandler->Init(env, playerObject, NULL); 315 316 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 317 NSString *sourceURIString = NSStringFromJavaString(env, sourceURI); 318 if (!sourceURIString) { 319 LOGGER_ERRORMSG("OSXMediaPlayer: Unable to create sourceURIString\n"); 320 ThrowJavaException(env, "com/sun/media/jfxmedia/MediaException", 321 "OSXMediaPlayer: Unable to create sourceURIString"); 322 return; 323 } 324 325 NSURL *mediaURL = [[NSURL alloc] initWithString:sourceURIString]; 326 if (!mediaURL) { 327 LOGGER_WARNMSG("OSXMediaPlayer: Unable to create mediaURL\n"); 328 ThrowJavaException(env, "com/sun/media/jfxmedia/MediaException", 329 "OSXMediaPlayer: Unable to create mediaURL"); 330 return; 331 } 332 333 OSXMediaPlayer *player = [[OSXMediaPlayer alloc] initWithURL:mediaURL javaPlayer:playerObject andEnv:env eventHandler:eventHandler]; 334 if (!player) { 335 LOGGER_WARNMSG("OSXMediaPlayer: Unable to create player\n"); 336 ThrowJavaException(env, "com/sun/media/jfxmedia/MediaException", 337 "OSXMediaPlayer: Unable to create player"); 338 [mediaURL release]; 339 return; 340 } 341 342 [player release]; // The player peer list retains for us 343 [pool drain]; 344 } 345 346 /* 347 * Class: com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer 348 * Method: osxGetAudioEqualizerRef 349 * Signature: ()J 350 */ 351 JNIEXPORT jlong JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxGetAudioEqualizerRef 352 (JNIEnv *env, jobject playerObject) { 353 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 354 OSXMediaPlayer *player = [OSXMediaPlayer peerForPlayer:playerObject andEnv:env]; 355 CAudioEqualizer *eq = 0; 356 if (player) { 357 eq = player.audioEqualizer; 358 } 359 [pool drain]; 360 return ptr_to_jlong(eq); 361 } 362 363 /* 364 * Class: com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer 365 * Method: osxGetAudioSpectrumRef 366 * Signature: ()J 367 */ 368 JNIEXPORT jlong JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxGetAudioSpectrumRef 369 (JNIEnv *env, jobject playerObject) { 370 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 371 OSXMediaPlayer *player = [OSXMediaPlayer peerForPlayer:playerObject andEnv:env]; 372 CAudioSpectrum *spectrum = NULL; 373 if (player) { 374 spectrum = player.audioSpectrum; 375 } 376 [pool drain]; 377 return ptr_to_jlong(spectrum); 378 } 379 380 /* 381 * Class: com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer 382 * Method: osxGetAudioSyncDelay 383 * Signature: ()J 384 */ 385 JNIEXPORT jlong JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxGetAudioSyncDelay 386 (JNIEnv *env, jobject playerObject) 387 { 388 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 389 OSXMediaPlayer *player = [OSXMediaPlayer peerForPlayer:playerObject andEnv:env]; 390 jlong asd = 0; 391 if (player) { 392 asd = (jlong)player.audioSyncDelay; 393 } 394 [pool drain]; 395 return asd; 396 } 397 398 /* 399 * Class: com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer 400 * Method: osxSetAudioSyncDelay 401 * Signature: (J)V 402 */ 403 JNIEXPORT void JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxSetAudioSyncDelay 404 (JNIEnv *env, jobject playerObject, jlong delay) 405 { 406 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 407 OSXMediaPlayer *player = [OSXMediaPlayer peerForPlayer:playerObject andEnv:env]; 408 if (player) { 409 player.audioSyncDelay = (int64_t)delay; 410 } 411 [pool drain]; 412 } 413 414 /* 415 * Class: com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer 416 * Method: osxPlay 417 * Signature: ()V 418 */ 419 JNIEXPORT void JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxPlay 420 (JNIEnv *env, jobject playerObject) 421 { 422 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 423 OSXMediaPlayer *player = [OSXMediaPlayer peerForPlayer:playerObject andEnv:env]; 424 if (player) { 425 [player play]; 426 } 427 [pool drain]; 428 } 429 430 /* 431 * Class: com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer 432 * Method: osxStop 433 * Signature: ()V 434 */ 435 JNIEXPORT void JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxStop 436 (JNIEnv *env, jobject playerObject) 437 { 438 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 439 OSXMediaPlayer *player = [OSXMediaPlayer peerForPlayer:playerObject andEnv:env]; 440 if (player) { 441 [player stop]; 442 } 443 [pool drain]; 444 } 445 446 /* 447 * Class: com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer 448 * Method: osxPause 449 * Signature: ()V 450 */ 451 JNIEXPORT void JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxPause 452 (JNIEnv *env, jobject playerObject) 453 { 454 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 455 OSXMediaPlayer *player = [OSXMediaPlayer peerForPlayer:playerObject andEnv:env]; 456 if (player) { 457 [player pause]; 458 } 459 [pool drain]; 460 } 461 462 /* 463 * Class: com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer 464 * Method: osxFinish 465 * Signature: ()V 466 */ 467 JNIEXPORT void JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxFinish 468 (JNIEnv *env, jobject playerObject) 469 { 470 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 471 OSXMediaPlayer *player = [OSXMediaPlayer peerForPlayer:playerObject andEnv:env]; 472 if (player) { 473 [player finish]; 474 } 475 [pool drain]; 476 } 477 478 /* 479 * Class: com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer 480 * Method: osxGetRate 481 * Signature: ()F 482 */ 483 JNIEXPORT jfloat JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxGetRate 484 (JNIEnv *env, jobject playerObject) 485 { 486 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 487 OSXMediaPlayer *player = [OSXMediaPlayer peerForPlayer:playerObject andEnv:env]; 488 jfloat rc = 0.0; 489 if (player) { 490 rc = (jfloat)player.rate; 491 } 492 [pool drain]; 493 return rc; 494 } 495 496 /* 497 * Class: com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer 498 * Method: osxSetRate 499 * Signature: (F)V 500 */ 501 JNIEXPORT void JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxSetRate 502 (JNIEnv *env, jobject playerObject, jfloat rate) 503 { 504 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 505 OSXMediaPlayer *player = [OSXMediaPlayer peerForPlayer:playerObject andEnv:env]; 506 if (player) { 507 player.rate = (double)rate; 508 } 509 [pool drain]; 510 } 511 512 /* 513 * Class: com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer 514 * Method: osxGetPresentationTime 515 * Signature: ()D 516 */ 517 JNIEXPORT jdouble JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxGetPresentationTime 518 (JNIEnv *env, jobject playerObject) 519 { 520 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 521 OSXMediaPlayer *player = [OSXMediaPlayer peerForPlayer:playerObject andEnv:env]; 522 jdouble rc = 0.0; 523 if (player) { 524 rc = player.currentTime; 525 } 526 [pool drain]; 527 return rc; 528 } 529 530 /* 531 * Class: com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer 532 * Method: osxGetMute 533 * Signature: ()Z 534 */ 535 JNIEXPORT jboolean JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxGetMute 536 (JNIEnv *env, jobject playerObject) 537 { 538 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 539 OSXMediaPlayer *player = [OSXMediaPlayer peerForPlayer:playerObject andEnv:env]; 540 jboolean rc = JNI_FALSE; 541 if (player) { 542 rc = (player.mute != NO); 543 } 544 [pool drain]; 545 return rc; 546 } 547 548 /* 549 * Class: com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer 550 * Method: osxSetMute 551 * Signature: (Z)V 552 */ 553 JNIEXPORT void JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxSetMute 554 (JNIEnv *env, jobject playerObject, jboolean mute) 555 { 556 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 557 OSXMediaPlayer *player = [OSXMediaPlayer peerForPlayer:playerObject andEnv:env]; 558 if (player) { 559 player.mute = (mute != JNI_FALSE); 560 } 561 [pool drain]; 562 } 563 564 /* 565 * Class: com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer 566 * Method: osxGetVolume 567 * Signature: ()F 568 */ 569 JNIEXPORT jfloat JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxGetVolume 570 (JNIEnv *env, jobject playerObject) 571 { 572 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 573 OSXMediaPlayer *player = [OSXMediaPlayer peerForPlayer:playerObject andEnv:env]; 574 jfloat rc = 0.0; 575 if (player) { 576 rc = (jfloat)player.volume; 577 } 578 [pool drain]; 579 return rc; 580 } 581 582 /* 583 * Class: com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer 584 * Method: osxSetVolume 585 * Signature: (F)V 586 */ 587 JNIEXPORT void JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxSetVolume 588 (JNIEnv *env, jobject playerObject, jfloat volume) 589 { 590 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 591 OSXMediaPlayer *player = [OSXMediaPlayer peerForPlayer:playerObject andEnv:env]; 592 if (player) { 593 player.volume = (double)volume; 594 } 595 [pool drain]; 596 } 597 598 /* 599 * Class: com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer 600 * Method: osxGetBalance 601 * Signature: ()F 602 */ 603 JNIEXPORT jfloat JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxGetBalance 604 (JNIEnv *env, jobject playerObject) 605 { 606 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 607 OSXMediaPlayer *player = [OSXMediaPlayer peerForPlayer:playerObject andEnv:env]; 608 jfloat rc = 0.0; 609 if (player) { 610 rc = (jfloat)player.balance; 611 } 612 [pool drain]; 613 return rc; 614 } 615 616 /* 617 * Class: com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer 618 * Method: osxSetBalance 619 * Signature: (F)V 620 */ 621 JNIEXPORT void JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxSetBalance 622 (JNIEnv *env, jobject playerObject, jfloat balance) 623 { 624 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 625 OSXMediaPlayer *player = [OSXMediaPlayer peerForPlayer:playerObject andEnv:env]; 626 if (player) { 627 player.balance = (double)balance; 628 } 629 [pool drain]; 630 } 631 632 /* 633 * Class: com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer 634 * Method: osxGetDuration 635 * Signature: ()D 636 */ 637 JNIEXPORT jdouble JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxGetDuration 638 (JNIEnv *env, jobject playerObject) 639 { 640 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 641 OSXMediaPlayer *player = [OSXMediaPlayer peerForPlayer:playerObject andEnv:env]; 642 double duration = -1.0; 643 if (player) { 644 duration = (jdouble)player.duration; 645 } 646 [pool drain]; 647 return duration; 648 } 649 650 /* 651 * Class: com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer 652 * Method: osxSeek 653 * Signature: (D)V 654 */ 655 JNIEXPORT void JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxSeek 656 (JNIEnv *env, jobject playerObject, jdouble time) 657 { 658 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 659 OSXMediaPlayer *player = [OSXMediaPlayer peerForPlayer:playerObject andEnv:env]; 660 if (player) { 661 player.currentTime = (double)time; 662 } 663 [pool drain]; 664 } 665 666 /* 667 * Class: com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer 668 * Method: osxDispose 669 * Signature: ()V 670 */ 671 JNIEXPORT void JNICALL Java_com_sun_media_jfxmediaimpl_platform_osx_OSXMediaPlayer_osxDispose 672 (JNIEnv *env, jobject playerObject) 673 { 674 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 675 OSXMediaPlayer *player = [OSXMediaPlayer peerForPlayer:playerObject andEnv:env]; 676 if (player) { 677 [player dispose]; 678 679 // This should pop the last retain, aside from the autoreleased reference... 680 [OSXMediaPlayer removePlayerPeers:player]; 681 } 682 [pool drain]; 683 }