https://bugs.webkit.org/show_bug.cgi?id=144332
Reviewed by Jer Noble.
* Modules/mediasession/WebMediaSessionManager.cpp:
(WebCore::WebMediaSessionManager::externalOutputDeviceAvailableDidChange): Always make client
callback, let them decide if it is significant or not.
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::HTMLMediaElement): m_loadTimer -> m_pendingActionTimer.
(WebCore::HTMLMediaElement::scheduleDelayedAction): Handle CheckPlaybackTargetCompatablity.
(WebCore::HTMLMediaElement::scheduleNextSourceChild): m_loadTimer -> m_pendingActionTimer.
(WebCore::HTMLMediaElement::loadTimerFired): Renamed pendingActionTimerFired.
(WebCore::HTMLMediaElement::prepareForLoad): m_loadTimer -> m_pendingActionTimer.
(WebCore::HTMLMediaElement::setDefaultPlaybackRate): Add logging.
(WebCore::HTMLMediaElement::clearMediaPlayer): m_loadTimer -> m_pendingActionTimer.
(WebCore::HTMLMediaElement::webkitCurrentPlaybackTargetIsSupported): Removed.
(WebCore::HTMLMediaElement::dispatchEvent): If a 'webkitcurrentplaybacktargetiswirelesschanged'
event is dispatched when the current target is wireless but the media engine does not support
wireless playback, tell the media engine not to play to the target.
* html/HTMLMediaElement.h:
* html/HTMLMediaElement.idl:
* html/HTMLMediaSession.cpp:
(WebCore::HTMLMediaSession::showPlaybackTargetPicker): Drive-by fix to disallow audio-only files.
(WebCore::HTMLMediaSession::currentPlaybackTargetIsSupported): Deleted.
* html/HTMLMediaSession.h:
* platform/graphics/MediaPlayer.cpp:
(WebCore::MediaPlayer::isCurrentPlaybackTargetSupported): Deleted.
* platform/graphics/MediaPlayer.h:
* platform/graphics/MediaPlayerPrivate.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::MediaPlayerPrivateAVFoundationObjC::setShouldPlayToPlaybackTarget): Use a RetainPtr
to explicitly manage the lifetime of the temporary object.
(WebCore::MediaPlayerPrivateAVFoundationObjC::isPlayingToWirelessPlaybackTarget): Ditto.
* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::setShouldPlayToPlaybackTarget):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::isCurrentPlaybackTargetWireless):
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::isCurrentPlaybackTargetSupported): Deleted.
* platform/graphics/mac/MediaPlayerPrivateQTKit.h:
* platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
(WebCore::MediaPlayerPrivateQTKit::setShouldPlayToPlaybackTarget):
(WebCore::MediaPlayerPrivateQTKit::isCurrentPlaybackTargetWireless):
(WebCore::MediaPlayerPrivateQTKit::isCurrentPlaybackTargetSupported): Deleted.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@183509
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2015-04-28 Eric Carlson <eric.carlson@apple.com>
+
+ [Mac] Simplify code to support media engines which do not support target playback
+ https://bugs.webkit.org/show_bug.cgi?id=144332
+
+ Reviewed by Jer Noble.
+
+ * Modules/mediasession/WebMediaSessionManager.cpp:
+ (WebCore::WebMediaSessionManager::externalOutputDeviceAvailableDidChange): Always make client
+ callback, let them decide if it is significant or not.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::HTMLMediaElement): m_loadTimer -> m_pendingActionTimer.
+ (WebCore::HTMLMediaElement::scheduleDelayedAction): Handle CheckPlaybackTargetCompatablity.
+ (WebCore::HTMLMediaElement::scheduleNextSourceChild): m_loadTimer -> m_pendingActionTimer.
+ (WebCore::HTMLMediaElement::loadTimerFired): Renamed pendingActionTimerFired.
+ (WebCore::HTMLMediaElement::prepareForLoad): m_loadTimer -> m_pendingActionTimer.
+ (WebCore::HTMLMediaElement::setDefaultPlaybackRate): Add logging.
+ (WebCore::HTMLMediaElement::clearMediaPlayer): m_loadTimer -> m_pendingActionTimer.
+ (WebCore::HTMLMediaElement::webkitCurrentPlaybackTargetIsSupported): Removed.
+ (WebCore::HTMLMediaElement::dispatchEvent): If a 'webkitcurrentplaybacktargetiswirelesschanged'
+ event is dispatched when the current target is wireless but the media engine does not support
+ wireless playback, tell the media engine not to play to the target.
+ * html/HTMLMediaElement.h:
+ * html/HTMLMediaElement.idl:
+
+ * html/HTMLMediaSession.cpp:
+ (WebCore::HTMLMediaSession::showPlaybackTargetPicker): Drive-by fix to disallow audio-only files.
+ (WebCore::HTMLMediaSession::currentPlaybackTargetIsSupported): Deleted.
+ * html/HTMLMediaSession.h:
+
+ * platform/graphics/MediaPlayer.cpp:
+ (WebCore::MediaPlayer::isCurrentPlaybackTargetSupported): Deleted.
+ * platform/graphics/MediaPlayer.h:
+ * platform/graphics/MediaPlayerPrivate.h:
+
+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+ (WebCore::MediaPlayerPrivateAVFoundationObjC::setShouldPlayToPlaybackTarget): Use a RetainPtr
+ to explicitly manage the lifetime of the temporary object.
+ (WebCore::MediaPlayerPrivateAVFoundationObjC::isPlayingToWirelessPlaybackTarget): Ditto.
+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
+
+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
+ (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::setShouldPlayToPlaybackTarget):
+ (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::isCurrentPlaybackTargetWireless):
+ (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::isCurrentPlaybackTargetSupported): Deleted.
+
+ * platform/graphics/mac/MediaPlayerPrivateQTKit.h:
+ * platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
+ (WebCore::MediaPlayerPrivateQTKit::setShouldPlayToPlaybackTarget):
+ (WebCore::MediaPlayerPrivateQTKit::isCurrentPlaybackTargetWireless):
+ (WebCore::MediaPlayerPrivateQTKit::isCurrentPlaybackTargetSupported): Deleted.
+
2015-04-28 Alex Christensen <achristensen@webkit.org>
[Content Extensions] Use less memory for CombinedURLFilters.
void WebMediaSessionManager::externalOutputDeviceAvailableDidChange(bool available)
{
- if (m_externalOutputDeviceAvailable == available)
- return;
-
m_externalOutputDeviceAvailable = available;
for (auto& state : m_clientState)
state->client->externalOutputDeviceAvailableDidChange(state->contextId, available);
HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& document, bool createdByParser)
: HTMLElement(tagName, document)
, ActiveDOMObject(&document)
- , m_loadTimer(*this, &HTMLMediaElement::loadTimerFired)
+ , m_pendingActionTimer(*this, &HTMLMediaElement::pendingActionTimerFired)
, m_progressEventTimer(*this, &HTMLMediaElement::progressEventTimerFired)
, m_playbackProgressTimer(*this, &HTMLMediaElement::playbackProgressTimerFired)
, m_scanTimer(*this, &HTMLMediaElement::scanTimerFired)
setFlags(m_pendingActionFlags, TextTrackChangesNotification);
#endif
- m_loadTimer.startOneShot(0);
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+ if (actionType & CheckPlaybackTargetCompatablity)
+ setFlags(m_pendingActionFlags, CheckPlaybackTargetCompatablity);
+#endif
+
+ m_pendingActionTimer.startOneShot(0);
}
void HTMLMediaElement::scheduleNextSourceChild()
{
// Schedule the timer to try the next <source> element WITHOUT resetting state ala prepareForLoad.
setFlags(m_pendingActionFlags, LoadMediaResource);
- m_loadTimer.startOneShot(0);
+ m_pendingActionTimer.startOneShot(0);
}
void HTMLMediaElement::scheduleEvent(const AtomicString& eventName)
m_asyncEventQueue.enqueueEvent(event.release());
}
-void HTMLMediaElement::loadTimerFired()
+void HTMLMediaElement::pendingActionTimerFired()
{
Ref<HTMLMediaElement> protect(*this); // loadNextSourceChild may fire 'beforeload', which can make arbitrary DOM mutations.
notifyMediaPlayerOfTextTrackChanges();
#endif
+#if ENABLE(WIRELESS_PLAYBACK_TARGET)
+ if (m_pendingActionFlags & CheckPlaybackTargetCompatablity && m_player && m_player->isCurrentPlaybackTargetWireless() && !m_player->canPlayToWirelessPlaybackTarget()) {
+ LOG(Media, "HTMLMediaElement::pendingActionTimerFired(%p) - calling setShouldPlayToPlaybackTarget(false)", this);
+ m_player->setShouldPlayToPlaybackTarget(false);
+ }
+#endif
+
m_pendingActionFlags = 0;
}
// Perform the cleanup required for the resource load algorithm to run.
stopPeriodicTimers();
- m_loadTimer.stop();
+ m_pendingActionTimer.stop();
// FIXME: Figure out appropriate place to reset LoadTextTrackResource if necessary and set m_pendingActionFlags to 0 here.
m_pendingActionFlags &= ~LoadMediaResource;
m_sentEndEvent = false;
void HTMLMediaElement::setDefaultPlaybackRate(double rate)
{
if (m_defaultPlaybackRate != rate) {
+ LOG(Media, "HTMLMediaElement::setDefaultPlaybackRate(%p) - %f", this, rate);
m_defaultPlaybackRate = rate;
scheduleEvent(eventNames().ratechangeEvent);
}
m_player = nullptr;
stopPeriodicTimers();
- m_loadTimer.stop();
+ m_pendingActionTimer.stop();
clearFlags(m_pendingActionFlags, flags);
m_loadState = WaitingForSource;
return m_mediaSession->currentPlaybackTargetIsWireless(*this);
}
-bool HTMLMediaElement::webkitCurrentPlaybackTargetIsSupported() const
-{
- return m_mediaSession->currentPlaybackTargetIsSupported(*this);
-}
-
void HTMLMediaElement::wirelessRoutesAvailableDidChange()
{
enqueuePlaybackTargetAvailabilityChangedEvent();
LOG(Media, "HTMLMediaElement::mediaPlayerCurrentPlaybackTargetIsWirelessChanged(%p) - webkitCurrentPlaybackTargetIsWireless = %s", this, boolString(webkitCurrentPlaybackTargetIsWireless()));
scheduleEvent(eventNames().webkitcurrentplaybacktargetiswirelesschangedEvent);
-#if ENABLE(WIRELESS_PLAYBACK_TARGET)
m_mediaSession->mediaStateDidChange(*this, mediaState());
-#endif
+}
+
+bool HTMLMediaElement::dispatchEvent(PassRefPtr<Event> prpEvent)
+{
+ RefPtr<Event> event = prpEvent;
+ if (event->type() == eventNames().webkitcurrentplaybacktargetiswirelesschangedEvent)
+ scheduleDelayedAction(CheckPlaybackTargetCompatablity);
+ return HTMLElement::dispatchEvent(event);
}
bool HTMLMediaElement::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
ConfigureTextTracks = 1 << 1,
TextTrackChangesNotification = 1 << 2,
ConfigureTextTrackDisplay = 1 << 3,
+ CheckPlaybackTargetCompatablity = 1 << 4,
- EveryDelayedAction = LoadMediaResource | ConfigureTextTracks | TextTrackChangesNotification | ConfigureTextTrackDisplay,
+ EveryDelayedAction = LoadMediaResource | ConfigureTextTracks | TextTrackChangesNotification | ConfigureTextTrackDisplay | CheckPlaybackTargetCompatablity,
};
void scheduleDelayedAction(DelayedActionType);
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
void webkitShowPlaybackTargetPicker();
bool webkitCurrentPlaybackTargetIsWireless() const;
- bool webkitCurrentPlaybackTargetIsSupported() const;
virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture) override;
virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) override;
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
virtual void mediaPlayerCurrentPlaybackTargetIsWirelessChanged(MediaPlayer*) override;
void enqueuePlaybackTargetAvailabilityChangedEvent();
+
+ using EventTarget::dispatchEvent;
+ virtual bool dispatchEvent(PassRefPtr<Event>) override;
#endif
virtual String mediaPlayerReferrer() const override;
virtual double mediaPlayerRequestedPlaybackRate() const override final;
- void loadTimerFired();
+ void pendingActionTimerFired();
void progressEventTimerFired();
void playbackProgressTimerFired();
void scanTimerFired();
void updateCaptionContainer();
- Timer m_loadTimer;
+ Timer m_pendingActionTimer;
Timer m_progressEventTimer;
Timer m_playbackProgressTimer;
Timer m_scanTimer;
[Conditional=WIRELESS_PLAYBACK_TARGET] void webkitShowPlaybackTargetPicker();
[Conditional=WIRELESS_PLAYBACK_TARGET] readonly attribute boolean webkitCurrentPlaybackTargetIsWireless;
- [Conditional=WIRELESS_PLAYBACK_TARGET] readonly attribute boolean webkitCurrentPlaybackTargetIsSupported;
};
return isWireless;
}
-bool HTMLMediaSession::currentPlaybackTargetIsSupported(const HTMLMediaElement& element) const
-{
- MediaPlayer* player = element.player();
- if (!player) {
- LOG(Media, "HTMLMediaSession::currentPlaybackTargetIsSupported - returning FALSE because player is NULL");
- return false;
- }
-
- bool isSupported = player->isCurrentPlaybackTargetSupported();
- LOG(Media, "HTMLMediaSession::currentPlaybackTargetIsSupported - returning %s", isSupported ? "TRUE" : "FALSE");
-
- return isSupported;
-}
-
void HTMLMediaSession::showPlaybackTargetPicker(const HTMLMediaElement& element)
{
LOG(Media, "HTMLMediaSession::showPlaybackTargetPicker");
return;
}
+#if !PLATFORM(IOS)
+ if (!element.hasVideo()) {
+ LOG(Media, "HTMLMediaSession::showPlaybackTargetPicker - returning early because element has no video");
+ return;
+ }
+#endif
+
element.document().showPlaybackTargetPicker(*this, is<HTMLVideoElement>(element));
}
LOG(Media, "HTMLMediaSession::mediaEngineUpdated");
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- setWirelessVideoPlaybackDisabled(element, m_restrictions & WirelessVideoPlaybackDisabled);
+ if (m_restrictions & WirelessVideoPlaybackDisabled)
+ setWirelessVideoPlaybackDisabled(element, true);
if (m_playbackTarget)
client().setWirelessPlaybackTarget(*m_playbackTarget.copyRef());
if (m_shouldPlayToPlaybackTarget)
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
void showPlaybackTargetPicker(const HTMLMediaElement&);
bool currentPlaybackTargetIsWireless(const HTMLMediaElement&) const;
- bool currentPlaybackTargetIsSupported(const HTMLMediaElement&) const;
bool hasWirelessPlaybackTargets(const HTMLMediaElement&) const;
bool wirelessVideoPlaybackDisabled(const HTMLMediaElement&) const;
return m_private->isCurrentPlaybackTargetWireless();
}
-bool MediaPlayer::isCurrentPlaybackTargetSupported() const
-{
- return m_private->isCurrentPlaybackTargetSupported();
-}
-
String MediaPlayer::wirelessPlaybackTargetName() const
{
return m_private->wirelessPlaybackTargetName();
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
bool isCurrentPlaybackTargetWireless() const;
- bool isCurrentPlaybackTargetSupported() const;
enum WirelessPlaybackTargetType { TargetTypeNone, TargetTypeAirPlay, TargetTypeTVOut };
WirelessPlaybackTargetType wirelessPlaybackTargetType() const;
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
virtual bool isCurrentPlaybackTargetWireless() const { return false; }
- virtual bool isCurrentPlaybackTargetSupported() const { return true; }
virtual String wirelessPlaybackTargetName() const { return emptyString(); }
virtual MediaPlayer::WirelessPlaybackTargetType wirelessPlaybackTargetType() const { return MediaPlayer::TargetTypeNone; }
return;
AVOutputContext *newContext = shouldPlay ? m_outputContext.get() : nil;
- AVOutputContext *currentContext = m_avPlayer.get().outputContext;
- if ((!newContext && !currentContext) || [currentContext isEqual:newContext])
+ RetainPtr<AVOutputContext> currentContext = m_avPlayer.get().outputContext;
+ if ((!newContext && !currentContext.get()) || [currentContext.get() isEqual:newContext])
return;
setDelayCallbacks(true);
if (!m_avPlayer)
return false;
- if (!m_outputContext || !m_outputContext.get().deviceName)
- return false;
-
- return m_cachedRate;
+ RetainPtr<AVOutputContext> currentContext = m_avPlayer.get().outputContext;
+ return currentContext && currentContext.get().deviceName;
}
#endif // !PLATFORM(IOS)
virtual MediaTime totalFrameDelay() override;
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- virtual bool isCurrentPlaybackTargetSupported() const override;
+ virtual bool isCurrentPlaybackTargetWireless() const override;
virtual void setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&&);
virtual void setShouldPlayToPlaybackTarget(bool) override;
#endif
bool m_hasAvailableVideoFrame;
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
RefPtr<MediaPlaybackTarget> m_playbackTarget;
- bool m_currentPlaybackTargetIsSupported { true };
+ bool m_shouldPlayToTarget { false };
#endif
};
}
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
-bool MediaPlayerPrivateMediaSourceAVFObjC::isCurrentPlaybackTargetSupported() const
-{
- if (!m_playbackTarget)
- return true;
-
- return !m_playbackTarget->hasActiveRoute();
-}
-
void MediaPlayerPrivateMediaSourceAVFObjC::setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&& target)
{
m_playbackTarget = WTF::move(target);
void MediaPlayerPrivateMediaSourceAVFObjC::setShouldPlayToPlaybackTarget(bool shouldPlayToTarget)
{
- bool oldSupported = m_currentPlaybackTargetIsSupported;
- m_currentPlaybackTargetIsSupported = !shouldPlayToTarget;
+ if (shouldPlayToTarget == m_shouldPlayToTarget)
+ return;
+
+ m_shouldPlayToTarget = shouldPlayToTarget;
- if (m_player && oldSupported != m_currentPlaybackTargetIsSupported)
+ if (m_player)
m_player->currentPlaybackTargetIsWirelessChanged();
}
+
+bool MediaPlayerPrivateMediaSourceAVFObjC::isCurrentPlaybackTargetWireless() const
+{
+ if (!m_playbackTarget)
+ return false;
+
+ return m_shouldPlayToTarget && m_playbackTarget->hasActiveRoute();
+}
#endif
}
virtual long platformErrorCode() const;
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- virtual bool isCurrentPlaybackTargetSupported() const override;
+ virtual bool isCurrentPlaybackTargetWireless() const override;
virtual void setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&&);
virtual void setShouldPlayToPlaybackTarget(bool) override;
- void togglePlayingToPlaybackTarget();
#endif
MediaPlayer* m_player;
mutable FloatSize m_cachedNaturalSize;
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
RefPtr<MediaPlaybackTarget> m_playbackTarget;
- bool m_currentPlaybackTargetIsSupported { true };
+ bool m_shouldPlayToTarget { false };
#endif
};
}
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
-bool MediaPlayerPrivateQTKit::isCurrentPlaybackTargetSupported() const
-{
- if (!m_playbackTarget)
- return true;
-
- return !m_playbackTarget->hasActiveRoute();
-}
-
void MediaPlayerPrivateQTKit::setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&& target)
{
m_playbackTarget = WTF::move(target);
void MediaPlayerPrivateQTKit::setShouldPlayToPlaybackTarget(bool shouldPlayToTarget)
{
- bool oldSupported = m_currentPlaybackTargetIsSupported;
- m_currentPlaybackTargetIsSupported = !shouldPlayToTarget;
+ if (shouldPlayToTarget == m_shouldPlayToTarget)
+ return;
- if (m_player && oldSupported != m_currentPlaybackTargetIsSupported)
+ m_shouldPlayToTarget = shouldPlayToTarget;
+
+ if (m_player)
m_player->currentPlaybackTargetIsWirelessChanged();
}
+
+bool MediaPlayerPrivateQTKit::isCurrentPlaybackTargetWireless() const
+{
+ if (!m_playbackTarget)
+ return false;
+
+ return m_shouldPlayToTarget && m_playbackTarget->hasActiveRoute();
+}
#endif
} // namespace WebCore