1 /* 2 * Copyright (c) 2011, 2018, 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 #include "config.h" 27 28 #include "GraphicsContext.h" 29 #include <wtf/java/JavaEnv.h> 30 #include "MediaPlayerPrivateJava.h" 31 #include "NotImplemented.h" 32 #include "PlatformContextJava.h" 33 34 #include "Document.h" 35 #include "Settings.h" 36 37 #include <wtf/text/CString.h> // todo tav remove when building w/ pch 38 39 #include "com_sun_webkit_graphics_WCMediaPlayer.h" 40 #include "com_sun_webkit_graphics_GraphicsDecoder.h" 41 42 43 namespace WebCore { 44 45 46 ///////////////////////// log support 47 48 #if defined(NDEBUG) 49 50 #define LOG_TRACE0(szFormat) ((void)0) 51 #define LOG_TRACE1(szFormat, p1) ((void)0) 52 #define LOG_TRACE2(szFormat, p1, p2) ((void)0) 53 #define LOG_TRACE3(szFormat, p1, p2, p3) ((void)0) 54 #define LOG_TRACE4(szFormat, p1, p2, p3, p4) ((void)0) 55 56 #define LOG_ERROR0(szFormat) ((void)0) 57 #define LOG_ERROR1(szFormat, p1) ((void)0) 58 59 #define PLOG_TRACE0(szFormat) ((void)0) 60 #define PLOG_TRACE1(szFormat, p1) ((void)0) 61 #define PLOG_TRACE2(szFormat, p1, p2) ((void)0) 62 #define PLOG_TRACE3(szFormat, p1, p2, p3) ((void)0) 63 #define PLOG_TRACE4(szFormat, p1, p2, p3, p4) ((void)0) 64 65 #define PLOG_ERROR0(szFormat) ((void)0) 66 #define PLOG_ERROR1(szFormat, p1) ((void)0) 67 68 #else 69 70 #include <stdio.h> 71 #include "wtf/CurrentTime.h" 72 #include "wtf/Threading.h" 73 74 const char* networkStateStr(MediaPlayer::NetworkState networkState) { 75 switch (networkState) { 76 case MediaPlayer::Empty: 77 return "Empty"; 78 case MediaPlayer::Idle: 79 return "Idle"; 80 case MediaPlayer::Loading: 81 return "Loading"; 82 case MediaPlayer::Loaded: 83 return "Loaded"; 84 case MediaPlayer::FormatError: 85 return "FormatError"; 86 case MediaPlayer::NetworkError: 87 return "NetworkError"; 88 case MediaPlayer::DecodeError: 89 return "DecodeError"; 90 } 91 return "<unknown network state>"; 92 } 93 94 const char* readyStateStr(MediaPlayer::ReadyState readyState) { 95 switch (readyState) { 96 case MediaPlayer::HaveNothing: 97 return "HaveNothing"; 98 case MediaPlayer::HaveMetadata: 99 return "HaveMetadata"; 100 case MediaPlayer::HaveCurrentData: 101 return "HaveCurrentData"; 102 case MediaPlayer::HaveFutureData: 103 return "HaveFutureData"; 104 case MediaPlayer::HaveEnoughData: 105 return "HaveEnoughData"; 106 } 107 return "<unknown ready state>"; 108 } 109 110 namespace Logger { 111 112 FILE* getLogStream() { 113 FILE *stream = stderr; 114 //FILE *stream = fopen("webVideo.log", "a"); 115 return stream; 116 } 117 118 void releaseLogStream(FILE *stream) { 119 fflush(stream); 120 //fclose(stream); 121 } 122 123 void AMLogf(const char* szLevel, const char* szFormat, ...) { 124 FILE *stream = getLogStream(); 125 fprintf(stream, "[%s (native)] ", szLevel); 126 va_list args; 127 va_start(args, szFormat); 128 vfprintf(stream, szFormat, args); 129 releaseLogStream(stream); 130 } 131 132 void AMLogf_p(const MediaPlayerPrivate *p, const char* szLevel, const char* szFormat, ...) { 133 FILE *stream = getLogStream(); 134 fprintf(stream, "[%s (native),states:(%s,%s), paused:%d, seeking:%d, pos:%f/%f]", 135 szLevel, networkStateStr(p->networkState()), readyStateStr(p->readyState()), 136 (p->paused() ? 1 : 0), (p->seeking() ? 1 : 0), 137 p->currentTime(), p->duration()); 138 va_list args; 139 va_start(args, szFormat); 140 vfprintf(stream, szFormat, args); 141 releaseLogStream(stream); 142 } 143 } 144 145 #define LOG_TRACE0(szFormat) Logger::AMLogf("INFO", szFormat) 146 #define LOG_TRACE1(szFormat, p1) Logger::AMLogf("INFO", szFormat, p1) 147 #define LOG_TRACE2(szFormat, p1, p2) Logger::AMLogf("INFO", szFormat, p1, p2) 148 #define LOG_TRACE3(szFormat, p1, p2, p3) Logger::AMLogf("INFO", szFormat, p1, p2, p3) 149 #define LOG_TRACE4(szFormat, p1, p2, p3, p4) Logger::AMLogf("INFO", szFormat, p1, p2, p3, p4) 150 151 #define LOG_ERROR0(szFormat) Logger::AMLogf("SEVERE", szFormat) 152 #define LOG_ERROR1(szFormat, p1) Logger::AMLogf("SEVERE", szFormat, p1) 153 154 #define PLOG_TRACE0(szFormat) Logger::AMLogf_p(this, "INFO", szFormat) 155 #define PLOG_TRACE1(szFormat, p1) Logger::AMLogf_p(this, "INFO", szFormat, p1) 156 #define PLOG_TRACE2(szFormat, p1, p2) Logger::AMLogf_p(this, "INFO", szFormat, p1, p2) 157 #define PLOG_TRACE3(szFormat, p1, p2, p3) Logger::AMLogf_p(this, "INFO", szFormat, p1, p2, p3) 158 #define PLOG_TRACE4(szFormat, p1, p2, p3, p4) Logger::AMLogf_p(this, "INFO", szFormat, p1, p2, p3, p4) 159 160 #define PLOG_ERROR0(szFormat) Logger::AMLogf_p(this, "SEVERE", szFormat) 161 #define PLOG_ERROR1(szFormat, p1) Logger::AMLogf_p(this, "SEVERE", szFormat, p1) 162 163 #endif 164 165 //////////////////////// 166 167 168 169 170 void MediaPlayerPrivate::registerMediaEngine(MediaEngineRegistrar registrar) 171 { 172 LOG_TRACE0(">>registerMediaEngine\n"); 173 JNIEnv* env = WebCore_GetJavaEnv(); 174 jclass playerCls = PG_GetMediaPlayerClass(env); 175 if (!playerCls) { 176 LOG_ERROR0("<<registerMediaEngine ERROR: MediaPlayer class is unavailable\n"); 177 return; 178 } 179 //CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType, 180 //MediaEngineGetSitesInMediaCache, MediaEngineClearMediaCache, MediaEngineClearMediaCacheForSite 181 registrar([] (MediaPlayer* player) { return std::unique_ptr<MediaPlayerPrivate>(new MediaPlayerPrivate(player)); }, 182 MediaEngineSupportedTypes, MediaEngineSupportsType, 0, 0, 0, 0); 183 } 184 185 void MediaPlayerPrivate::MediaEngineSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& types) 186 { 187 LOG_TRACE0(">>MediaEngineSupportedTypes\n"); 188 HashSet<String, ASCIICaseInsensitiveHash>& supportedTypes = GetSupportedTypes(); 189 for (const auto& type : supportedTypes) { 190 types.add(type); 191 } 192 LOG_TRACE0("<<MediaEngineSupportedTypes\n"); 193 } 194 195 MediaPlayer::SupportsType MediaPlayerPrivate::MediaEngineSupportsType(const MediaEngineSupportParameters& parameters) 196 { 197 for (const auto& codecValue: parameters.type.codecs()) { 198 UNUSED_PARAM(codecValue); 199 LOG_TRACE2(">>MediaEngineSupportsType, type=%s, codecs=%s\n", parameters.type.raw().utf8().data(), codecValue.utf8().data()); 200 } 201 202 if (parameters.type.isEmpty()) { 203 LOG_TRACE0("<<MediaEngineSupportsType: NOT supported (type is empty)\n"); 204 return MediaPlayer::IsNotSupported; 205 } 206 207 if (GetSupportedTypes().contains(parameters.type.containerType())) { 208 LOG_TRACE0("<<MediaEngineSupportsType: MayBeSupported/IsSupported\n"); 209 auto codecs = parameters.type.parameter(ContentType::codecsParameter()); 210 return codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported; 211 } 212 LOG_TRACE0("<<MediaEngineSupportsType: NOT supported\n"); 213 return MediaPlayer::IsNotSupported; 214 } 215 216 HashSet<String, ASCIICaseInsensitiveHash>& MediaPlayerPrivate::GetSupportedTypes() 217 { 218 static HashSet<String, ASCIICaseInsensitiveHash> supportedTypes; 219 // TODO: refresh after change 220 221 if (!supportedTypes.isEmpty()) { 222 return supportedTypes; 223 } 224 225 JNIEnv* env = WebCore_GetJavaEnv(); 226 static jmethodID s_mID = env->GetMethodID(PG_GetGraphicsManagerClass(env), 227 "getSupportedMediaTypes", "()[Ljava/lang/String;"); 228 ASSERT(s_mID); 229 230 JLocalRef<jobjectArray> jArray( 231 (jobjectArray)env->CallObjectMethod(PL_GetGraphicsManager(env), s_mID)); 232 ASSERT(jArray); 233 CheckAndClearException(env); 234 235 jsize len = env->GetArrayLength(jArray); 236 for (jsize i=0; i<len; i++) { 237 JLString jStr((jstring)env->GetObjectArrayElement(jArray, i)); 238 String s(env, jStr); 239 supportedTypes.add(s); 240 } 241 242 return supportedTypes; 243 } 244 245 246 // ********************************************************* 247 // MediaPlayerPrivate 248 // ********************************************************* 249 MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer *player) 250 : m_player(player) 251 , m_networkState(MediaPlayer::Empty) 252 , m_readyState(MediaPlayer::HaveNothing) 253 , m_isVisible(false) 254 , m_hasVideo(false) 255 , m_hasAudio(false) 256 , m_paused(true) 257 , m_seeking(false) 258 , m_seekTime(0) 259 , m_duration(0) 260 , m_bytesLoaded(0) 261 , m_didLoadingProgress(false) 262 { 263 JNIEnv* env = WebCore_GetJavaEnv(); 264 static jmethodID mid = env->GetMethodID(PG_GetGraphicsManagerClass(env), 265 "fwkCreateMediaPlayer", "(J)Lcom/sun/webkit/graphics/WCMediaPlayer;"); 266 ASSERT(mid); 267 268 JLocalRef<jobject> obj(env->CallObjectMethod(PL_GetGraphicsManager(env), 269 mid, ptr_to_jlong(this))); 270 ASSERT(obj); 271 CheckAndClearException(env); 272 273 m_buffered = std::make_unique<PlatformTimeRanges>(); 274 m_jPlayer = RQRef::create(obj); 275 } 276 277 MediaPlayerPrivate::~MediaPlayerPrivate() 278 { 279 WC_GETJAVAENV_CHKRET(env); 280 static jmethodID s_mID 281 = env->GetMethodID(PG_GetMediaPlayerClass(env), "fwkDispose", "()V"); 282 ASSERT(s_mID); 283 284 env->CallVoidMethod(*m_jPlayer, s_mID); 285 CheckAndClearException(env); 286 } 287 288 void MediaPlayerPrivate::load(const String& url) 289 { 290 if (m_networkState == MediaPlayer::Loading) { 291 cancelLoad(); 292 } 293 294 String userAgent; 295 // MediaPlayerClient mpClient = m_player->client(); 296 // Document* doc = mpClient.mediaPlayerOwningDocument(); //XXX: mediaPlayerOwningDocument removed 297 // if (doc != NULL && doc->settings() != NULL) { 298 // userAgent = doc->settings()->userAgent(); 299 // } 300 301 JNIEnv* env = WebCore_GetJavaEnv(); 302 static jmethodID s_mID 303 = env->GetMethodID(PG_GetMediaPlayerClass(env), "fwkLoad", "(Ljava/lang/String;Ljava/lang/String;)V"); 304 ASSERT(s_mID); 305 306 env->CallVoidMethod(*m_jPlayer, s_mID, 307 (jstring)url.toJavaString(env), 308 userAgent.isEmpty() ? NULL : (jstring)userAgent.toJavaString(env)); 309 CheckAndClearException(env); 310 } 311 312 void MediaPlayerPrivate::cancelLoad() 313 { 314 m_paused = true; 315 m_seeking = false; 316 317 JNIEnv* env = WebCore_GetJavaEnv(); 318 static jmethodID s_mID 319 = env->GetMethodID(PG_GetMediaPlayerClass(env), "fwkCancelLoad", "()V"); 320 ASSERT(s_mID); 321 322 env->CallVoidMethod(*m_jPlayer, s_mID); 323 CheckAndClearException(env); 324 } 325 326 void MediaPlayerPrivate::prepareToPlay() 327 { 328 JNIEnv* env = WebCore_GetJavaEnv(); 329 static jmethodID s_mID 330 = env->GetMethodID(PG_GetMediaPlayerClass(env), "fwkPrepareToPlay", "()V"); 331 ASSERT(s_mID); 332 333 env->CallVoidMethod(*m_jPlayer, s_mID); 334 CheckAndClearException(env); 335 } 336 337 //PlatformMedia MediaPlayerPrivate::platformMedia() const { return NoPlatformMedia; } 338 339 //#if USE(ACCELERATED_COMPOSITING) 340 // PlatformLayer* MediaPlayerPrivate::platformLayer() const { return 0; } 341 //#endif 342 343 void MediaPlayerPrivate::play() 344 { 345 PLOG_TRACE0(">>MediaPlayerPrivate::play\n"); 346 347 if (!paused()) { 348 PLOG_TRACE0("<<MediaPlayerPrivate::play - already playing\n"); 349 return; 350 } 351 352 JNIEnv* env = WebCore_GetJavaEnv(); 353 static jmethodID s_mID 354 = env->GetMethodID(PG_GetMediaPlayerClass(env), "fwkPlay", "()V"); 355 ASSERT(s_mID); 356 357 env->CallVoidMethod(*m_jPlayer, s_mID); 358 CheckAndClearException(env); 359 360 PLOG_TRACE0("<<MediaPlayerPrivate::play\n"); 361 } 362 363 void MediaPlayerPrivate::pause() 364 { 365 if (paused()) { 366 return; 367 } 368 369 JNIEnv* env = WebCore_GetJavaEnv(); 370 static jmethodID s_mID 371 = env->GetMethodID(PG_GetMediaPlayerClass(env), "fwkPause", "()V"); 372 ASSERT(s_mID); 373 374 env->CallVoidMethod(*m_jPlayer, s_mID); 375 CheckAndClearException(env); 376 } 377 378 //bool MediaPlayerPrivate::supportsFullscreen() const { return false; } 379 //bool MediaPlayerPrivate::supportsSave() const { return false; } 380 381 FloatSize MediaPlayerPrivate::naturalSize() const 382 { 383 // PLOG_TRACE2("MediaPlayerPrivate naturalSize - return %d x %d\n", m_naturalSize.width(), m_naturalSize.height()); 384 return m_naturalSize; 385 } 386 387 bool MediaPlayerPrivate::hasVideo() const 388 { 389 // PLOG_TRACE1("MediaPlayerPrivate hasVideo - return %d\n", m_hasVideo ? 1 : 0); 390 return m_hasVideo; 391 } 392 393 bool MediaPlayerPrivate::hasAudio() const 394 { 395 // PLOG_TRACE1("MediaPlayerPrivate hasAudio - return %d\n", m_hasAudio ? 1 : 0); 396 return m_hasAudio; 397 } 398 399 void MediaPlayerPrivate::setVisible(bool visible) 400 { 401 if (m_isVisible != visible) { 402 PLOG_TRACE2("MediaPlayerPrivate setVisible: %d => %d\n", m_isVisible ? 1 : 0, visible ? 1 : 0); 403 m_isVisible = visible; 404 } 405 } 406 407 float MediaPlayerPrivate::duration() const 408 { 409 // return numeric_limits<float>::infinity(); // "live" stream 410 return m_duration; 411 } 412 413 float MediaPlayerPrivate::currentTime() const 414 { 415 if (m_seeking) { 416 LOG_TRACE1("MediaPlayerPrivate currentTime returns (seekTime): %f\n", m_seekTime); 417 return m_seekTime; 418 } 419 JNIEnv* env = WebCore_GetJavaEnv(); 420 static jmethodID s_mID 421 = env->GetMethodID(PG_GetMediaPlayerClass(env), "fwkGetCurrentTime", "()F"); 422 ASSERT(s_mID); 423 424 double result = env->CallFloatMethod(*m_jPlayer, s_mID); 425 CheckAndClearException(env); 426 427 // LOG_TRACE1("MediaPlayerPrivate currentTime returns: %f\n", (float)result); 428 429 return (float)result; 430 } 431 432 void MediaPlayerPrivate::seek(float time) 433 { 434 PLOG_TRACE1(">>MediaPlayerPrivate::seek(%f)\n", time); 435 436 m_seekTime = time; 437 438 JNIEnv* env = WebCore_GetJavaEnv(); 439 static jmethodID s_mID 440 = env->GetMethodID(PG_GetMediaPlayerClass(env), "fwkSeek", "(F)V"); 441 ASSERT(s_mID); 442 443 env->CallVoidMethod(*m_jPlayer, s_mID, time); 444 CheckAndClearException(env); 445 446 PLOG_TRACE1("<<MediaPlayerPrivate::seek(%f)\n", time); 447 } 448 449 bool MediaPlayerPrivate::seeking() const 450 { 451 return m_seeking; 452 } 453 454 MediaTime MediaPlayerPrivate::startTime() const 455 { 456 // always 0 457 return MediaTime::zeroTime(); 458 } 459 460 void MediaPlayerPrivate::setRate(float rate) 461 { 462 JNIEnv* env = WebCore_GetJavaEnv(); 463 static jmethodID s_mID 464 = env->GetMethodID(PG_GetMediaPlayerClass(env), "fwkSetRate", "(F)V"); 465 ASSERT(s_mID); 466 467 env->CallVoidMethod(*m_jPlayer, s_mID, rate); 468 CheckAndClearException(env); 469 } 470 471 void MediaPlayerPrivate::setPreservesPitch(bool preserve) 472 { 473 JNIEnv* env = WebCore_GetJavaEnv(); 474 static jmethodID s_mID 475 = env->GetMethodID(PG_GetMediaPlayerClass(env), "fwkSetPreservesPitch", "(Z)V"); 476 ASSERT(s_mID); 477 478 env->CallVoidMethod(*m_jPlayer, s_mID, bool_to_jbool(preserve)); 479 CheckAndClearException(env); 480 } 481 482 bool MediaPlayerPrivate::paused() const 483 { 484 return m_paused; 485 } 486 487 void MediaPlayerPrivate::setVolume(float volume) 488 { 489 JNIEnv* env = WebCore_GetJavaEnv(); 490 static jmethodID s_mID 491 = env->GetMethodID(PG_GetMediaPlayerClass(env), "fwkSetVolume", "(F)V"); 492 ASSERT(s_mID); 493 494 env->CallVoidMethod(*m_jPlayer, s_mID, volume); 495 CheckAndClearException(env); 496 } 497 498 bool MediaPlayerPrivate::supportsMuting() const 499 { 500 return true; 501 } 502 503 void MediaPlayerPrivate::setMuted(bool mute) 504 { 505 JNIEnv* env = WebCore_GetJavaEnv(); 506 static jmethodID 507 s_mID = env->GetMethodID(PG_GetMediaPlayerClass(env), "fwkSetMute", "(Z)V"); 508 ASSERT(s_mID); 509 510 env->CallVoidMethod(*m_jPlayer, s_mID, bool_to_jbool(mute)); 511 CheckAndClearException(env); 512 } 513 514 //bool MediaPlayerPrivate::hasClosedCaptions() const { return false; } 515 //void MediaPlayerPrivate::setClosedCaptionsVisible(bool) { } 516 517 MediaPlayer::NetworkState MediaPlayerPrivate::networkState() const 518 { 519 // LOG_TRACE1("MediaPlayerPrivate networkState - return %d\n", (int)m_networkState); 520 return m_networkState; 521 } 522 523 MediaPlayer::ReadyState MediaPlayerPrivate::readyState() const 524 { 525 // LOG_TRACE1("MediaPlayerPrivate readyState - return %d\n", (int)m_readyState); 526 return m_readyState; 527 } 528 529 float MediaPlayerPrivate::maxTimeSeekable() const 530 { 531 return m_duration; 532 } 533 534 bool MediaPlayerPrivate::didLoadingProgress() const 535 { 536 bool didLoadingProgress = m_didLoadingProgress; 537 m_didLoadingProgress = false; 538 PLOG_TRACE1("MediaPlayerPrivate didLoadingProgress - returning %d", didLoadingProgress ? 1 : 0); 539 return didLoadingProgress; 540 } 541 542 std::unique_ptr<PlatformTimeRanges> MediaPlayerPrivate::buffered() const 543 { 544 return std::make_unique<PlatformTimeRanges>(); //XXX recheck; USE m_buffered 545 } 546 547 unsigned MediaPlayerPrivate::bytesLoaded() const 548 { 549 return m_bytesLoaded; 550 } 551 552 void MediaPlayerPrivate::setSize(const IntSize& size) 553 { 554 JNIEnv* env = WebCore_GetJavaEnv(); 555 static jmethodID s_mID 556 = env->GetMethodID(PG_GetMediaPlayerClass(env), "fwkSetSize", "(II)V"); 557 ASSERT(s_mID); 558 559 env->CallVoidMethod(*m_jPlayer, s_mID, (jint)size.width(), (jint)size.height()); 560 CheckAndClearException(env); 561 } 562 563 void MediaPlayerPrivate::paint(GraphicsContext& gc, const FloatRect& r) 564 { 565 // PLOG_TRACE4(">>MediaPlayerPrivate paint (%d, %d), [%d x %d]\n", r.x(), r.y(), r.width(), r.height()); 566 if (gc.paintingDisabled()) { 567 PLOG_TRACE0("<<MediaPlayerPrivate paint (!gc or paintingDisabled)\n"); 568 return; 569 } 570 if (!m_isVisible) { 571 PLOG_TRACE0("<<MediaPlayerPrivate paint (!visible)\n"); 572 return; 573 } 574 575 gc.platformContext()->rq().freeSpace(24) 576 << (jint)com_sun_webkit_graphics_GraphicsDecoder_RENDERMEDIAPLAYER 577 << m_jPlayer << (jint)r.x() << (jint)r.y() 578 << (jint)r.width() << (jint)r.height(); 579 580 // PLOG_TRACE0("<<MediaPlayerPrivate paint (OK)\n"); 581 } 582 583 //void MediaPlayerPrivate::paintCurrentFrameInContext(GraphicsContext* c, const IntRect& r) { paint(c, r); } 584 585 void MediaPlayerPrivate::setPreload(MediaPlayer::Preload preload) 586 { 587 // enum Preload { None, MetaData, Auto }; 588 PLOG_TRACE1("MediaPlayerPrivate setPreload, preload=%u\n", (int)preload); 589 jint jPreload = 590 (preload == MediaPlayer::None) ? com_sun_webkit_graphics_WCMediaPlayer_PRELOAD_NONE 591 : (preload == MediaPlayer::MetaData) ? com_sun_webkit_graphics_WCMediaPlayer_PRELOAD_METADATA 592 : (preload == MediaPlayer::Auto) ? com_sun_webkit_graphics_WCMediaPlayer_PRELOAD_AUTO 593 : -1; 594 if (jPreload < 0) { 595 // unexpected preload value 596 return; 597 } 598 JNIEnv* env = WebCore_GetJavaEnv(); 599 static jmethodID s_mID 600 = env->GetMethodID(PG_GetMediaPlayerClass(env), "fwkSetPreload", "(I)V"); 601 ASSERT(s_mID); 602 603 env->CallVoidMethod(*m_jPlayer, s_mID, jPreload); 604 CheckAndClearException(env); 605 } 606 607 //bool MediaPlayerPrivate::hasAvailableVideoFrame() const { return readyState() >= MediaPlayer::HaveCurrentData; } 608 609 //bool MediaPlayerPrivate::canLoadPoster() const { return false; } 610 //void MediaPlayerPrivate::setPoster(const String&) { } 611 612 //#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) 613 // virtual void deliverNotification(MediaPlayerProxyNotificationType) = 0; 614 // virtual void setMediaPlayerProxy(WebMediaPlayerProxy*) = 0; 615 //#endif 616 617 //#if USE(ACCELERATED_COMPOSITING) 618 // // whether accelerated rendering is supported by the media engine for the current media. 619 // virtual bool supportsAcceleratedRendering() const { return false; } 620 // // called when the rendering system flips the into or out of accelerated rendering mode. 621 // virtual void acceleratedRenderingStateChanged() { } 622 //#endif 623 624 //bool MediaPlayerPrivate::hasSingleSecurityOrigin() const { return false; } 625 626 //MediaPlayer::MovieLoadType MediaPlayerPrivate::movieLoadType() const { return MediaPlayer::Unknown; } 627 628 void MediaPlayerPrivate::setNetworkState(MediaPlayer::NetworkState networkState) 629 { 630 if (m_networkState != networkState) { 631 PLOG_TRACE4("MediaPlayerPrivate NetworkState: %s (%d) => %s (%d)\n", 632 networkStateStr(m_networkState), (int)m_networkState, networkStateStr(networkState), (int)networkState); 633 m_networkState = networkState; 634 m_player->networkStateChanged(); 635 } 636 } 637 638 void MediaPlayerPrivate::setReadyState(MediaPlayer::ReadyState readyState) 639 { 640 if (m_readyState != readyState) { 641 PLOG_TRACE4("MediaPlayerPrivate ReadyState: %s (%d) => %s (%d)\n", 642 readyStateStr(m_readyState), (int)m_readyState, readyStateStr(readyState), (int)readyState); 643 m_readyState = readyState; 644 m_player->readyStateChanged(); 645 } 646 } 647 648 649 MediaPlayerPrivate* MediaPlayerPrivate::getPlayer(jlong ptr) 650 { 651 return reinterpret_cast<MediaPlayerPrivate *>(jlong_to_ptr(ptr)); 652 } 653 654 void MediaPlayerPrivate::notifyNetworkStateChanged(int networkState) 655 { 656 switch (networkState) { 657 case com_sun_webkit_graphics_WCMediaPlayer_NETWORK_STATE_EMPTY: 658 setNetworkState(MediaPlayer::Empty); 659 break; 660 case com_sun_webkit_graphics_WCMediaPlayer_NETWORK_STATE_IDLE: 661 setNetworkState(MediaPlayer::Idle); 662 break; 663 case com_sun_webkit_graphics_WCMediaPlayer_NETWORK_STATE_LOADING: 664 setNetworkState(MediaPlayer::Loading); 665 break; 666 case com_sun_webkit_graphics_WCMediaPlayer_NETWORK_STATE_LOADED: 667 setNetworkState(MediaPlayer::Loaded); 668 break; 669 case com_sun_webkit_graphics_WCMediaPlayer_NETWORK_STATE_FORMAT_ERROR: 670 setNetworkState(MediaPlayer::FormatError); 671 break; 672 case com_sun_webkit_graphics_WCMediaPlayer_NETWORK_STATE_NETWORK_ERROR: 673 setNetworkState(MediaPlayer::NetworkError); 674 break; 675 case com_sun_webkit_graphics_WCMediaPlayer_NETWORK_STATE_DECODE_ERROR: 676 setNetworkState(MediaPlayer::DecodeError); 677 break; 678 } 679 } 680 681 void MediaPlayerPrivate::notifyReadyStateChanged(int readyState) 682 { 683 switch (readyState) { 684 case com_sun_webkit_graphics_WCMediaPlayer_READY_STATE_HAVE_NOTHING: 685 setReadyState(MediaPlayer::HaveNothing); 686 break; 687 case com_sun_webkit_graphics_WCMediaPlayer_READY_STATE_HAVE_METADATA: 688 setReadyState(MediaPlayer::HaveMetadata); 689 break; 690 case com_sun_webkit_graphics_WCMediaPlayer_READY_STATE_HAVE_CURRENT_DATA: 691 setReadyState(MediaPlayer::HaveCurrentData); 692 break; 693 case com_sun_webkit_graphics_WCMediaPlayer_READY_STATE_HAVE_FUTURE_DATA: 694 setReadyState(MediaPlayer::HaveFutureData); 695 break; 696 case com_sun_webkit_graphics_WCMediaPlayer_READY_STATE_HAVE_ENOUGH_DATA: 697 setReadyState(MediaPlayer::HaveEnoughData); 698 break; 699 } 700 } 701 702 void MediaPlayerPrivate::notifyPaused(bool paused) 703 { 704 PLOG_TRACE2(">>MediaPlayerPrivate notifyPaused: %d => %d\n", m_paused ? 1 : 0, paused ? 1 : 0); 705 706 if (m_paused != paused) { 707 m_paused = paused; 708 m_player->playbackStateChanged(); 709 } 710 } 711 712 void MediaPlayerPrivate::notifySeeking(bool seeking) 713 { 714 PLOG_TRACE2(">>MediaPlayerPrivate notifySeeking: %d => %d\n", m_seeking ? 1 : 0, seeking ? 1 : 0); 715 if (m_seeking != seeking) { 716 m_seeking = seeking; 717 if (!seeking) { 718 // notify time change after seek completed 719 //LOG_TRACE0("==MediaPlayerPrivate notifySeeking: NOTIFYING time changed\n"); 720 m_player->timeChanged(); 721 } 722 } 723 } 724 725 void MediaPlayerPrivate::notifyFinished() { 726 PLOG_TRACE0(">>MediaPlayerPrivate notifyFinished\n"); 727 m_player->timeChanged(); 728 } 729 730 void MediaPlayerPrivate::notifyReady(bool hasVideo, bool hasAudio) 731 { 732 PLOG_TRACE2(">>MediaPlayerPrivate notifyReady: hasVideo=%d, hasAudio=%d\n", hasVideo ? 1 : 0, hasAudio ? 1 : 0); 733 m_hasVideo = hasVideo; 734 m_hasAudio = hasAudio; 735 PLOG_TRACE0("<<MediaPlayerPrivate notifyReady\n"); 736 } 737 738 void MediaPlayerPrivate::notifyDurationChanged(float duration) 739 { 740 PLOG_TRACE2(">>MediaPlayerPrivate notifyDurationChanged, %f => %f\n", 741 m_duration, duration); 742 m_duration = duration; 743 m_player->durationChanged(); 744 } 745 746 void MediaPlayerPrivate::notifySizeChanged(int width, int height) 747 { 748 PLOG_TRACE2("MediaPlayerPrivate notifySizeChanged: %d x %d\n", width, height); 749 m_naturalSize = FloatSize(width, height); //XXX leave it as IntSize? 750 } 751 752 void MediaPlayerPrivate::notifyNewFrame() 753 { 754 PLOG_TRACE0(">>MediaPlayerPrivate notifyNewFrame\n"); 755 m_player->repaint(); 756 //PLOG_TRACE0("<<MediaPlayerPrivate notifyNewFrame\n"); 757 } 758 759 void MediaPlayerPrivate::notifyBufferChanged(std::unique_ptr<PlatformTimeRanges> timeRanges, int bytesLoaded) 760 { 761 PLOG_TRACE0("MediaPlayerPrivate notifyBufferChanged\n"); 762 m_buffered = std::move(timeRanges); 763 m_bytesLoaded = bytesLoaded; 764 m_didLoadingProgress = true; 765 } 766 767 768 // ********************************************************* 769 // JNI functions 770 // ********************************************************* 771 extern "C" { 772 JNIEXPORT void JNICALL Java_com_sun_webkit_graphics_WCMediaPlayer_notifyNetworkStateChanged 773 (JNIEnv*, jobject, jlong ptr, jint networkState) 774 { 775 MediaPlayerPrivate* player = MediaPlayerPrivate::getPlayer(ptr); 776 player->notifyNetworkStateChanged(networkState); 777 } 778 779 JNIEXPORT void JNICALL Java_com_sun_webkit_graphics_WCMediaPlayer_notifyReadyStateChanged 780 (JNIEnv*, jobject, jlong ptr, jint readyState) 781 { 782 MediaPlayerPrivate* player = MediaPlayerPrivate::getPlayer(ptr); 783 player->notifyReadyStateChanged(readyState); 784 } 785 786 JNIEXPORT void JNICALL Java_com_sun_webkit_graphics_WCMediaPlayer_notifyPaused 787 (JNIEnv*, jobject, jlong ptr, jboolean paused) 788 { 789 MediaPlayerPrivate* player = MediaPlayerPrivate::getPlayer(ptr); 790 player->notifyPaused(jbool_to_bool(paused)); 791 } 792 793 JNIEXPORT void JNICALL Java_com_sun_webkit_graphics_WCMediaPlayer_notifySeeking 794 (JNIEnv*, jobject, jlong ptr, jboolean seeking, jint /*readyState*/) 795 { 796 MediaPlayerPrivate* player = MediaPlayerPrivate::getPlayer(ptr); 797 player->notifySeeking(jbool_to_bool(seeking)); 798 } 799 800 JNIEXPORT void JNICALL Java_com_sun_webkit_graphics_WCMediaPlayer_notifyFinished 801 (JNIEnv*, jobject, jlong ptr) 802 { 803 MediaPlayerPrivate* player = MediaPlayerPrivate::getPlayer(ptr); 804 player->notifyFinished(); 805 } 806 807 JNIEXPORT void JNICALL Java_com_sun_webkit_graphics_WCMediaPlayer_notifyReady 808 (JNIEnv*, jobject, jlong ptr, jboolean hasVideo, jboolean hasAudio, jfloat duration) 809 { 810 MediaPlayerPrivate* player = MediaPlayerPrivate::getPlayer(ptr); 811 player->notifyReady(jbool_to_bool(hasVideo), jbool_to_bool(hasAudio)); 812 if (duration >= 0) { 813 player->notifyDurationChanged(duration); 814 } 815 } 816 817 JNIEXPORT void JNICALL Java_com_sun_webkit_graphics_WCMediaPlayer_notifyDurationChanged 818 (JNIEnv*, jobject, jlong ptr, jfloat duration) 819 { 820 MediaPlayerPrivate* player = MediaPlayerPrivate::getPlayer(ptr); 821 if (duration != player->duration()) { 822 player->notifyDurationChanged(duration); 823 } 824 } 825 826 JNIEXPORT void JNICALL Java_com_sun_webkit_graphics_WCMediaPlayer_notifySizeChanged 827 (JNIEnv*, jobject, jlong ptr, jint width, jint height) 828 { 829 MediaPlayerPrivate* player = MediaPlayerPrivate::getPlayer(ptr); 830 player->notifySizeChanged(width, height); 831 } 832 833 JNIEXPORT void JNICALL Java_com_sun_webkit_graphics_WCMediaPlayer_notifyNewFrame 834 (JNIEnv*, jobject, jlong ptr) 835 { 836 MediaPlayerPrivate* player = MediaPlayerPrivate::getPlayer(ptr); 837 player->notifyNewFrame(); 838 } 839 840 JNIEXPORT void JNICALL Java_com_sun_webkit_graphics_WCMediaPlayer_notifyBufferChanged 841 (JNIEnv *env, jobject, jlong ptr, jfloatArray ranges, jint bytesLoaded) 842 { 843 MediaPlayerPrivate* player = MediaPlayerPrivate::getPlayer(ptr); 844 845 jboolean isCopy; 846 jint len = env->GetArrayLength(ranges); 847 jfloat* rangesElems = env->GetFloatArrayElements(ranges, &isCopy); 848 849 PlatformTimeRanges* timeRanges = new PlatformTimeRanges(); 850 for (int i = 0; i < len; i+=2) { 851 timeRanges->add(MediaTime::createWithDouble(rangesElems[i]), 852 MediaTime::createWithDouble(rangesElems[i+1])); 853 } 854 if (isCopy == JNI_TRUE) { 855 env->ReleaseFloatArrayElements(ranges, rangesElems, JNI_ABORT); 856 } 857 858 player->notifyBufferChanged(std::unique_ptr<PlatformTimeRanges>(timeRanges), bytesLoaded); 859 } 860 861 } // extern "C" 862 863 } // namespace WebCore 864