Revise Out-of-band VTT support for better integration with AVFoundation engine
authorbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Mar 2014 23:50:42 +0000 (23:50 +0000)
committerbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Mar 2014 23:50:42 +0000 (23:50 +0000)
https://bugs.webkit.org/show_bug.cgi?id=129749
<rdar://problem/16215701>

Reviewed by Eric Carlson.

Revise the platform handling of out-of-band text tracks so that we can keep AVFoundation
informed of track selections we make. Use a dummy out-of-band child of the existing text
track classes to avoid code duplication.

* WebCore.xcodeproj/project.pbxproj: Add new OutOfBandTextTrackPrivateAVF.h file.
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::parseAttribute): Notify player when OOB tracks change.
(WebCore::HTMLMediaElement::outOfBandTrackSources): Also pass track mode to platform backend.
* html/track/TextTrack.cpp:
(WebCore::TextTrack::platformTextTrack): Also pass track mode to constructor.
* html/track/TrackBase.cpp:
(WebCore::TrackBase::TrackBase): Move ownership of track unique identifier to this base class.
* html/track/TrackBase.h:
(WebCore::TrackBase::uniqueId): Ditto.
* platform/graphics/MediaPlayer.cpp:
(WebCore::MediaPlayer::notifyTrackModeChanged): Added stub to pass message to platform player.
* platform/graphics/MediaPlayer.h:
* platform/graphics/MediaPlayerPrivate.h:
(WebCore::MediaPlayerPrivateInterface::notifyTrackModeChanged): Stub for most platforms.
* platform/graphics/PlatformTextTrack.h:
(WebCore::PlatformTextTrack::create): Update for revised constructor (with 'mode' argument).
(WebCore::PlatformTextTrack::createOutOfBand): Ditto.
(WebCore::PlatformTextTrack::mode): Added.
(WebCore::PlatformTextTrack::captionMenuOffItem): Use revised constructor arguments.
(WebCore::PlatformTextTrack::captionMenuAutomaticItem): Ditto.
(WebCore::PlatformTextTrack::PlatformTextTrack): Ditto.
* platform/graphics/avfoundation/InbandTextTrackPrivateAVF.h: Change predicate to return enum indicating the category
of track (out-of-band, legacy closed caption, or in band).
* platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h:
(WebCore::MediaPlayerPrivateAVFoundation::notifyTrackModeChanged): Added.
* platform/graphics/avfoundation/cf/InbandTextTrackPrivateAVCF.h: Override predicate to return category enum.
* platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp: Revise to use new category enum.
* platform/graphics/avfoundation/objc/InbandTextTrackPrivateAVFObjC.h: Override predicate to return category enum.
that this is NOT an out-of-band track.
* platform/graphics/avfoundation/objc/InbandTextTrackPrivateLegacyAVFObjC.h: Ditto.
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::MediaPlayerPrivateAVFoundationObjC::notifyTrackModeChanged): Added implementation.
(WebCore::MediaPlayerPrivateAVFoundationObjC::processMediaSelectionOptions): Revise to handle out-of-band
track placeholders.
(WebCore::MediaPlayerPrivateAVFoundationObjC::setCurrentTrack): Modify to inform AVFoundation about any
out-of-band tracks we've selected.
(WebCore::MediaPlayerPrivateAVFoundationObjC::synchronizeTextTrackState): Added.
* platform/graphics/avfoundation/objc/OutOfBandTextTrackPrivateAVF.h: Added.
(WebCore::OutOfBandTextTrackPrivateAVF::create):
(WebCore::OutOfBandTextTrackPrivateAVF::processCue):
(WebCore::OutOfBandTextTrackPrivateAVF::resetCueValues):
(WebCore::OutOfBandTextTrackPrivateAVF::mediaSelectionOption):
(WebCore::OutOfBandTextTrackPrivateAVF::OutOfBandTextTrackPrivateAVF):
(WebCore::OutOfBandTextTrackPrivateAVF::processCueAttributes):
* platform/graphics/ios/InbandTextTrackPrivateAVFIOS.h: Override predicate to indicate
that this is NOT an out-of-band track.
* platform/graphics/ios/MediaPlayerPrivateIOS.mm:
(WebCore::MediaPlayerPrivateIOS::setSelectedTextTrack): Correct typo in logging text.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@165227 268f45cc-cd09-0410-ab3c-d52691b4dbfc

23 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/track/TextTrack.cpp
Source/WebCore/html/track/TrackBase.cpp
Source/WebCore/html/track/TrackBase.h
Source/WebCore/platform/graphics/MediaPlayer.cpp
Source/WebCore/platform/graphics/MediaPlayer.h
Source/WebCore/platform/graphics/MediaPlayerPrivate.h
Source/WebCore/platform/graphics/PlatformTextTrack.h
Source/WebCore/platform/graphics/avfoundation/InbandTextTrackPrivateAVF.h
Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp
Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h
Source/WebCore/platform/graphics/avfoundation/cf/InbandTextTrackPrivateAVCF.h
Source/WebCore/platform/graphics/avfoundation/cf/InbandTextTrackPrivateLegacyAVCF.h
Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp
Source/WebCore/platform/graphics/avfoundation/objc/InbandTextTrackPrivateAVFObjC.h
Source/WebCore/platform/graphics/avfoundation/objc/InbandTextTrackPrivateLegacyAVFObjC.h
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm
Source/WebCore/platform/graphics/avfoundation/objc/OutOfBandTextTrackPrivateAVF.h [new file with mode: 0644]
Source/WebCore/platform/graphics/ios/InbandTextTrackPrivateAVFIOS.h
Source/WebCore/platform/graphics/ios/MediaPlayerPrivateIOS.mm

index c6bbade..8080f95 100644 (file)
@@ -1,3 +1,66 @@
+2014-03-06  Brent Fulgham  <bfulgham@apple.com>
+
+        Revise Out-of-band VTT support for better integration with AVFoundation engine
+        https://bugs.webkit.org/show_bug.cgi?id=129749
+        <rdar://problem/16215701>
+
+        Reviewed by Eric Carlson.
+
+        Revise the platform handling of out-of-band text tracks so that we can keep AVFoundation
+        informed of track selections we make. Use a dummy out-of-band child of the existing text
+        track classes to avoid code duplication.
+
+        * WebCore.xcodeproj/project.pbxproj: Add new OutOfBandTextTrackPrivateAVF.h file.
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::parseAttribute): Notify player when OOB tracks change.
+        (WebCore::HTMLMediaElement::outOfBandTrackSources): Also pass track mode to platform backend.
+        * html/track/TextTrack.cpp:
+        (WebCore::TextTrack::platformTextTrack): Also pass track mode to constructor.
+        * html/track/TrackBase.cpp:
+        (WebCore::TrackBase::TrackBase): Move ownership of track unique identifier to this base class.
+        * html/track/TrackBase.h:
+        (WebCore::TrackBase::uniqueId): Ditto.
+        * platform/graphics/MediaPlayer.cpp:
+        (WebCore::MediaPlayer::notifyTrackModeChanged): Added stub to pass message to platform player.
+        * platform/graphics/MediaPlayer.h:
+        * platform/graphics/MediaPlayerPrivate.h:
+        (WebCore::MediaPlayerPrivateInterface::notifyTrackModeChanged): Stub for most platforms.
+        * platform/graphics/PlatformTextTrack.h:
+        (WebCore::PlatformTextTrack::create): Update for revised constructor (with 'mode' argument).
+        (WebCore::PlatformTextTrack::createOutOfBand): Ditto.
+        (WebCore::PlatformTextTrack::mode): Added.
+        (WebCore::PlatformTextTrack::captionMenuOffItem): Use revised constructor arguments.
+        (WebCore::PlatformTextTrack::captionMenuAutomaticItem): Ditto.
+        (WebCore::PlatformTextTrack::PlatformTextTrack): Ditto.
+        * platform/graphics/avfoundation/InbandTextTrackPrivateAVF.h: Change predicate to return enum indicating the category
+        of track (out-of-band, legacy closed caption, or in band).
+        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h:
+        (WebCore::MediaPlayerPrivateAVFoundation::notifyTrackModeChanged): Added.
+        * platform/graphics/avfoundation/cf/InbandTextTrackPrivateAVCF.h: Override predicate to return category enum.
+        * platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp: Revise to use new category enum.
+        * platform/graphics/avfoundation/objc/InbandTextTrackPrivateAVFObjC.h: Override predicate to return category enum.
+        that this is NOT an out-of-band track.
+        * platform/graphics/avfoundation/objc/InbandTextTrackPrivateLegacyAVFObjC.h: Ditto.
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::notifyTrackModeChanged): Added implementation.
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::processMediaSelectionOptions): Revise to handle out-of-band
+        track placeholders.
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::setCurrentTrack): Modify to inform AVFoundation about any
+        out-of-band tracks we've selected.
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::synchronizeTextTrackState): Added.
+        * platform/graphics/avfoundation/objc/OutOfBandTextTrackPrivateAVF.h: Added.
+        (WebCore::OutOfBandTextTrackPrivateAVF::create):
+        (WebCore::OutOfBandTextTrackPrivateAVF::processCue):
+        (WebCore::OutOfBandTextTrackPrivateAVF::resetCueValues):
+        (WebCore::OutOfBandTextTrackPrivateAVF::mediaSelectionOption):
+        (WebCore::OutOfBandTextTrackPrivateAVF::OutOfBandTextTrackPrivateAVF):
+        (WebCore::OutOfBandTextTrackPrivateAVF::processCueAttributes):
+        * platform/graphics/ios/InbandTextTrackPrivateAVFIOS.h: Override predicate to indicate
+        that this is NOT an out-of-band track.
+        * platform/graphics/ios/MediaPlayerPrivateIOS.mm:
+        (WebCore::MediaPlayerPrivateIOS::setSelectedTextTrack): Correct typo in logging text.
+
 2014-03-06  Thiago de Barros Lacerda  <thiago.lacerda@openbossa.org>
 
         [WebRTC] Updating createOffer and createAnswer methods to match WebRTC editor's draft of 01/27/2014
index 45b3c03..12964ab 100644 (file)
                7A24587B1021EAF4000A00AA /* InspectorDOMAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A2458791021EAF4000A00AA /* InspectorDOMAgent.cpp */; };
                7A24587C1021EAF4000A00AA /* InspectorDOMAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A24587A1021EAF4000A00AA /* InspectorDOMAgent.h */; settings = {ATTRIBUTES = (Private, ); }; };
                7A29BA6A187B7C1D00F29CEB /* TemporaryOpenGLSetting.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A29BA69187B781C00F29CEB /* TemporaryOpenGLSetting.cpp */; };
+               7A29F57218C69514004D0F81 /* OutOfBandTextTrackPrivateAVF.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A29F57118C69514004D0F81 /* OutOfBandTextTrackPrivateAVF.h */; };
                7A54857F14E02D51006AE05A /* InspectorHistory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A54857D14E02D51006AE05A /* InspectorHistory.cpp */; };
                7A54858014E02D51006AE05A /* InspectorHistory.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A54857E14E02D51006AE05A /* InspectorHistory.h */; };
                7A54881714E432A1006AE05A /* DOMPatchSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A54881514E432A1006AE05A /* DOMPatchSupport.h */; };
                7A24587A1021EAF4000A00AA /* InspectorDOMAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorDOMAgent.h; sourceTree = "<group>"; };
                7A29BA67187B732200F29CEB /* TemporaryOpenGLSetting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemporaryOpenGLSetting.h; sourceTree = "<group>"; };
                7A29BA69187B781C00F29CEB /* TemporaryOpenGLSetting.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TemporaryOpenGLSetting.cpp; sourceTree = "<group>"; };
+               7A29F57118C69514004D0F81 /* OutOfBandTextTrackPrivateAVF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OutOfBandTextTrackPrivateAVF.h; path = objc/OutOfBandTextTrackPrivateAVF.h; sourceTree = "<group>"; };
                7A54857D14E02D51006AE05A /* InspectorHistory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorHistory.cpp; sourceTree = "<group>"; };
                7A54857E14E02D51006AE05A /* InspectorHistory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorHistory.h; sourceTree = "<group>"; };
                7A54881514E432A1006AE05A /* DOMPatchSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMPatchSupport.h; sourceTree = "<group>"; };
                DF9AFD6F13FC31B00015FEB7 /* objc */ = {
                        isa = PBXGroup;
                        children = (
+                               7A29F57118C69514004D0F81 /* OutOfBandTextTrackPrivateAVF.h */,
                                CDE3A85617F6020400C5BE20 /* AudioTrackPrivateAVFObjC.h */,
                                CDE3A85517F6020400C5BE20 /* AudioTrackPrivateAVFObjC.mm */,
                                CD54A760180F9F7000B076C9 /* AudioTrackPrivateMediaSourceAVFObjC.cpp */,
                                4157AF8012F1FB0400A8C6F5 /* MediaControlsApple.h in Headers */,
                                CDAB6D2917C7DE6C00C60B34 /* MediaControlsHost.h in Headers */,
                                CDF2B004181F059C00F2B424 /* MediaDescription.h in Headers */,
+                               7A29F57218C69514004D0F81 /* OutOfBandTextTrackPrivateAVF.h in Headers */,
                                97205AB81239291000B17380 /* MediaDocument.h in Headers */,
                                FD6F252D13F5EF0E0065165F /* MediaElementAudioSourceNode.h in Headers */,
                                E44613AD0CD6331000FADA75 /* MediaError.h in Headers */,
index 3868428..da635cb 100644 (file)
@@ -1597,6 +1597,11 @@ void HTMLMediaElement::textTrackModeChanged(TextTrack* track)
 
     if (m_textTracks && m_textTracks->contains(track))
         m_textTracks->scheduleChangeEvent();
+
+#if ENABLE(AVF_CAPTIONS)
+    if (track->trackType() == TextTrack::TrackElement && m_player)
+        m_player->notifyTrackModeChanged();
+#endif
 }
 
 void HTMLMediaElement::videoTrackSelectedChanged(VideoTrack* track)
@@ -5538,8 +5543,6 @@ String HTMLMediaElement::mediaPlayerUserAgent() const
 #if ENABLE(AVF_CAPTIONS)
 Vector<RefPtr<PlatformTextTrack>> HTMLMediaElement::outOfBandTrackSources()
 {
-    static int uniqueId = 0;
-
     Vector<RefPtr<PlatformTextTrack>> outOfBandTrackSources;
     for (auto& trackElement : childrenOfType<HTMLTrackElement>(*this)) {
         
@@ -5564,8 +5567,18 @@ Vector<RefPtr<PlatformTextTrack>> HTMLMediaElement::outOfBandTrackSources()
             platformKind = PlatformTextTrack::Forced;
         else
             continue;
-
-        outOfBandTrackSources.append(PlatformTextTrack::createOutOfBand(trackElement.label(), trackElement.srclang(), url.string(), platformKind, ++uniqueId, trackElement.isDefault()));
+        
+        const AtomicString& mode = trackElement.track()->mode();
+        
+        PlatformTextTrack::TrackMode platformMode = PlatformTextTrack::Disabled;
+        if (TextTrack::hiddenKeyword() == mode)
+            platformMode = PlatformTextTrack::Hidden;
+        else if (TextTrack::disabledKeyword() == mode)
+            platformMode = PlatformTextTrack::Disabled;
+        else if (TextTrack::showingKeyword() == mode)
+            platformMode = PlatformTextTrack::Showing;
+        
+        outOfBandTrackSources.append(PlatformTextTrack::createOutOfBand(trackElement.label(), trackElement.srclang(), url.string(), platformMode, platformKind, trackElement.track()->uniqueId(), trackElement.isDefault()));
     }
     
     return outOfBandTrackSources;
index 10ae9cf..f3fa4a5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2011 Google Inc.  All rights reserved.
- * Copyright (C) 2011, 2012, 2013 Apple Inc.  All rights reserved.
+ * Copyright (C) 2011-2014 Apple Inc.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -550,8 +550,6 @@ bool TextTrack::hasCue(VTTCue* cue, VTTCue::CueMatchRules match)
 #if USE(PLATFORM_TEXT_TRACK_MENU)
 PassRefPtr<PlatformTextTrack> TextTrack::platformTextTrack()
 {
-    static int uniqueId = 0;
-
     if (m_platformTextTrack)
         return m_platformTextTrack;
 
@@ -577,7 +575,15 @@ PassRefPtr<PlatformTextTrack> TextTrack::platformTextTrack()
     else if (m_trackType == InBand)
         type = PlatformTextTrack::InBand;
 
-    m_platformTextTrack = PlatformTextTrack::create(this, label(), language(), platformKind, type, ++uniqueId);
+    PlatformTextTrack::TrackMode platformMode = PlatformTextTrack::Disabled;
+    if (TextTrack::hiddenKeyword() == mode())
+        platformMode = PlatformTextTrack::Hidden;
+    else if (TextTrack::disabledKeyword() == mode())
+        platformMode = PlatformTextTrack::Disabled;
+    else if (TextTrack::showingKeyword() == mode())
+        platformMode = PlatformTextTrack::Showing;
+
+    m_platformTextTrack = PlatformTextTrack::create(this, label(), language(), platformMode, platformKind, type, uniqueId());
 
     return m_platformTextTrack;
 }
index e93e9e9..5b4fbef 100644 (file)
 
 namespace WebCore {
 
+static int s_uniqueId = 0;
+
 TrackBase::TrackBase(Type type, const AtomicString& id, const AtomicString& label, const AtomicString& language)
     : m_mediaElement(0)
 #if ENABLE(MEDIA_SOURCE)
     , m_sourceBuffer(0)
 #endif
+    , m_uniqueId(++s_uniqueId)
     , m_id(id)
     , m_label(label)
     , m_language(language)
index 509f7a6..f312b49 100644 (file)
@@ -62,6 +62,8 @@ public:
 
     virtual void clearClient() = 0;
 
+    virtual int uniqueId() const { return m_uniqueId; }
+
 #if ENABLE(MEDIA_SOURCE)
     SourceBuffer* sourceBuffer() const { return m_sourceBuffer; }
     void setSourceBuffer(SourceBuffer* buffer) { m_sourceBuffer = buffer; }
@@ -85,6 +87,7 @@ protected:
 
 private:
     Type m_type;
+    int m_uniqueId;
     AtomicString m_id;
     AtomicString m_kind;
     AtomicString m_label;
index aa77a81..dadc3e4 100644 (file)
@@ -1272,6 +1272,12 @@ void MediaPlayer::setTextTrackRepresentation(TextTrackRepresentation* representa
 }
 
 #if ENABLE(AVF_CAPTIONS)
+void MediaPlayer::notifyTrackModeChanged()
+{
+    if (m_private)
+        m_private->notifyTrackModeChanged();
+}
+
 Vector<RefPtr<PlatformTextTrack>> MediaPlayer::outOfBandTrackSources()
 {
     if (!m_mediaPlayerClient)
index 2915f47..0daf5ae 100644 (file)
@@ -537,6 +537,7 @@ public:
     bool requiresTextTrackRepresentation() const;
     void setTextTrackRepresentation(TextTrackRepresentation*);
 #if ENABLE(AVF_CAPTIONS)
+    void notifyTrackModeChanged();
     Vector<RefPtr<PlatformTextTrack>> outOfBandTrackSources();
 #endif
 #endif
index ca2530e..7b7a704 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2009-2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -247,6 +247,10 @@ public:
     virtual unsigned long corruptedVideoFrames() { return 0; }
     virtual double totalFrameDelay() { return 0; }
 #endif
+
+#if ENABLE(AVF_CAPTIONS)
+    virtual void notifyTrackModeChanged() { }
+#endif
 };
 
 }
index 9f3f12f..0cf9ab0 100644 (file)
@@ -59,21 +59,27 @@ public:
         OutOfBand = 1,
         Script = 2
     };
-
-    static PassRefPtr<PlatformTextTrack> create(PlatformTextTrackClient* client, const String& label, const String& language, TrackKind kind, TrackType type, int uniqueId)
+    enum TrackMode {
+        Disabled,
+        Hidden,
+        Showing
+    };
+    
+    static PassRefPtr<PlatformTextTrack> create(PlatformTextTrackClient* client, const String& label, const String& language, TrackMode mode, TrackKind kind, TrackType type, int uniqueId)
     {
-        return adoptRef(new PlatformTextTrack(client, label, language, String(), kind, type, uniqueId, false));
+        return adoptRef(new PlatformTextTrack(client, label, language, String(), mode, kind, type, uniqueId, false));
     }
 
-    static PassRefPtr<PlatformTextTrack> createOutOfBand(const String& label, const String& language, const String& url, TrackKind kind, int uniqueId, bool isDefault)
+    static PassRefPtr<PlatformTextTrack> createOutOfBand(const String& label, const String& language, const String& url, TrackMode mode, TrackKind kind, int uniqueId, bool isDefault)
     {
-        return adoptRef(new PlatformTextTrack(nullptr, label, language, url, kind, OutOfBand, uniqueId, isDefault));
+        return adoptRef(new PlatformTextTrack(nullptr, label, language, url, mode, kind, OutOfBand, uniqueId, isDefault));
     }
 
     virtual ~PlatformTextTrack() { }
     
     TrackType type() const { return m_type; }
     TrackKind kind() const { return m_kind; }
+    TrackMode mode() const { return m_mode; }
     const String& label() const { return m_label; }
     const String& language() const { return m_language; }
     const String& url() const { return m_url; }
@@ -83,21 +89,22 @@ public:
 
     static PlatformTextTrack* captionMenuOffItem()
     {
-        static PlatformTextTrack* off = PlatformTextTrack::create(nullptr, "off menu item", "", Subtitle, InBand, 0).leakRef();
+        static PlatformTextTrack* off = PlatformTextTrack::create(nullptr, "off menu item", "", Showing, Subtitle, InBand, 0).leakRef();
         return off;
     }
 
     static PlatformTextTrack* captionMenuAutomaticItem()
     {
-        static PlatformTextTrack* automatic = PlatformTextTrack::create(nullptr, "automatic menu item", "", Subtitle, InBand, 0).leakRef();
+        static PlatformTextTrack* automatic = PlatformTextTrack::create(nullptr, "automatic menu item", "", Showing, Subtitle, InBand, 0).leakRef();
         return automatic;
     }
 
 protected:
-    PlatformTextTrack(PlatformTextTrackClient* client, const String& label, const String& language, const String& url, TrackKind kind, TrackType type, int uniqueId, bool isDefault)
+    PlatformTextTrack(PlatformTextTrackClient* client, const String& label, const String& language, const String& url, TrackMode mode, TrackKind kind, TrackType type, int uniqueId, bool isDefault)
         : m_label(label)
         , m_language(language)
         , m_url(url)
+        , m_mode(mode)
         , m_kind(kind)
         , m_type(type)
         , m_client(client)
@@ -109,6 +116,7 @@ protected:
     String m_label;
     String m_language;
     String m_url;
+    TrackMode m_mode;
     TrackKind m_kind;
     TrackType m_type;
     PlatformTextTrackClient* m_client;
index 6c1825e..0cc7a56 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -55,15 +55,20 @@ public:
     bool hasBeenReported() const { return m_hasBeenReported; }
     void setHasBeenReported(bool reported) { m_hasBeenReported = reported; }
 
-    void processCue(CFArrayRef, double);
-    void resetCueValues();
+    virtual void processCue(CFArrayRef, double);
+    virtual void resetCueValues();
 
     void beginSeeking();
     void endSeeking() { m_seeking = false; }
     bool seeking() const { return m_seeking; }
     
-    virtual bool isLegacyClosedCaptionsTrack() const = 0;
-
+    enum Category {
+        LegacyClosedCaption,
+        OutOfBand,
+        InBand
+    };
+    virtual Category textTrackCategory() const = 0;
+    
 protected:
     InbandTextTrackPrivateAVF(AVFInbandTrackParent*);
 
index 1a18384..c758e37 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -907,6 +907,10 @@ void MediaPlayerPrivateAVFoundation::dispatchNotification()
 void MediaPlayerPrivateAVFoundation::configureInbandTracks()
 {
     RefPtr<InbandTextTrackPrivateAVF> trackToEnable;
+    
+#if ENABLE(AVF_CAPTIONS)
+    synchronizeTextTrackState();
+#endif
 
     // AVFoundation can only emit cues for one track at a time, so enable the first track that is showing, or the first that
     // is hidden if none are showing. Otherwise disable all tracks.
index b8f5558..f5a22bd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -294,6 +294,10 @@ protected:
     virtual size_t extraMemoryCost() const override;
 
     virtual void trackModeChanged() override;
+#if ENABLE(AVF_CAPTIONS)
+    virtual void notifyTrackModeChanged() { }
+    virtual void synchronizeTextTrackState() { }
+#endif
     void processNewAndRemovedTextTracks(const Vector<RefPtr<InbandTextTrackPrivateAVF>>&);
     void clearTextTracks();
     Vector<RefPtr<InbandTextTrackPrivateAVF>> m_textTracks;
index b483898..7fac5bf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -55,7 +55,7 @@ public:
 
     virtual void disconnect() override;
 
-    virtual bool isLegacyClosedCaptionsTrack() const override { return false; }
+    virtual Category textTrackCategory() const override { return InBand; }
 
     AVCFMediaSelectionOptionRef mediaSelectionOption() const { return m_mediaSelectionOption.get(); }
 
index 62982c5..6bcee4b 100644 (file)
@@ -55,7 +55,7 @@ public:
 
     virtual void disconnect() override;
 
-    virtual bool isLegacyClosedCaptionsTrack() const override { return true; }
+    virtual Category textTrackCategory() const override { return LegacyClosedCaption; }
 
     AVCFPlayerItemTrackRef avPlayerItemTrack() const { return m_playerItemTrack.get(); }
 
index d9202ca..8bd9a61 100644 (file)
@@ -1032,7 +1032,7 @@ void MediaPlayerPrivateAVFoundationCF::processLegacyClosedCaptionsTracks()
 
         bool newCCTrack = true;
         for (unsigned i = removedTextTracks.size(); i > 0; --i) {
-            if (!removedTextTracks[i - 1]->isLegacyClosedCaptionsTrack())
+            if (removedTextTracks[i - 1]->textTrackCategory() != InbandTextTrackPrivateAVF::LegacyClosedCaption)
                 continue;
 
             RefPtr<InbandTextTrackPrivateLegacyAVCF> track = static_cast<InbandTextTrackPrivateLegacyAVCF*>(m_textTracks[i - 1].get());
@@ -1079,7 +1079,7 @@ void MediaPlayerPrivateAVFoundationCF::processMediaSelectionOptions()
         AVCFMediaSelectionOptionRef option = static_cast<AVCFMediaSelectionOptionRef>(CFArrayGetValueAtIndex(legibleOptions.get(), i));
         bool newTrack = true;
         for (unsigned i = removedTextTracks.size(); i > 0; --i) {
-            if (removedTextTracks[i - 1]->isLegacyClosedCaptionsTrack())
+            if (removedTextTracks[i - 1]->textTrackCategory() == InbandTextTrackPrivateAVF::LegacyClosedCaption)
                 continue;
 
             RefPtr<InbandTextTrackPrivateAVCF> track = static_cast<InbandTextTrackPrivateAVCF*>(removedTextTracks[i - 1].get());
@@ -1110,7 +1110,7 @@ void AVFWrapper::setCurrentTrack(InbandTextTrackPrivateAVF* track)
     m_currentTrack = track;
 
     if (track) {
-        if (track->isLegacyClosedCaptionsTrack())
+        if (track->textTrackCategory() == InbandTextTrackPrivateAVF::LegacyClosedCaption)
             AVCFPlayerSetClosedCaptionDisplayEnabled(avPlayer(), TRUE);
 #if HAVE(AVFOUNDATION_MEDIA_SELECTION_GROUP)
         else
index 273ae25..8dbd369 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -56,8 +56,8 @@ public:
 
     virtual void disconnect() override;
 
-    virtual bool isLegacyClosedCaptionsTrack() const override { return false; }
-
+    virtual Category textTrackCategory() const override { return InBand; }
+    
     AVMediaSelectionOption *mediaSelectionOption() const { return m_mediaSelectionOption.get(); }
 
 protected:
index b49ddd4..a57aa69 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -56,8 +56,8 @@ public:
 
     virtual void disconnect() override;
 
-    virtual bool isLegacyClosedCaptionsTrack() const override { return true; }
-
+    virtual Category textTrackCategory() const override { return LegacyClosedCaption; }
+    
     AVPlayerItemTrack *avPlayerItemTrack() const { return m_playerItemTrack.get(); }
 
 protected:
index 285f1d8..9d6f9bf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -116,7 +116,12 @@ public:
 #if ENABLE(IOS_AIRPLAY)
     void playbackTargetIsWirelessDidChange();
 #endif
-
+    
+#if ENABLE(AVF_CAPTIONS)
+    virtual void notifyTrackModeChanged() override;
+    virtual void synchronizeTextTrackState() override;
+#endif
+    
     WeakPtr<MediaPlayerPrivateAVFoundationObjC> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
 
 private:
index 4696d6e..ba21777 100644 (file)
@@ -42,6 +42,7 @@
 #import "GraphicsContextCG.h"
 #import "InbandTextTrackPrivateAVFObjC.h"
 #import "InbandTextTrackPrivateLegacyAVFObjC.h"
+#import "OutOfBandTextTrackPrivateAVF.h"
 #import "URL.h"
 #import "Logging.h"
 #import "PlatformTimeRanges.h"
@@ -83,7 +84,8 @@
 // Note: This must be defined before our SOFT_LINK macros:
 @class AVMediaSelectionOption;
 @interface AVMediaSelectionOption (OutOfBandExtensions)
-@property (nonatomic, readonly) NSString *outOfBandSource /*NS_AVAILABLE(TBD, TBD)*/;
+@property (nonatomic, readonly) NSString* outOfBandSource;
+@property (nonatomic, readonly) NSString* outOfBandIdentifier;
 @end
 #endif
 
@@ -534,6 +536,42 @@ static const NSArray* mediaDescriptionForKind(PlatformTextTrack::TrackKind kind)
 
     return [NSArray arrayWithObjects: AVMediaCharacteristicTranscribesSpokenDialogForAccessibility, nil];
 }
+    
+void MediaPlayerPrivateAVFoundationObjC::notifyTrackModeChanged()
+{
+    trackModeChanged();
+}
+    
+void MediaPlayerPrivateAVFoundationObjC::synchronizeTextTrackState()
+{
+    const Vector<RefPtr<PlatformTextTrack>>& outOfBandTrackSources = player()->outOfBandTrackSources();
+    
+    for (auto& textTrack : m_textTracks) {
+        if (textTrack->textTrackCategory() == InbandTextTrackPrivateAVF::OutOfBand)
+            continue;
+        
+        RefPtr<OutOfBandTextTrackPrivateAVF> trackPrivate = static_cast<OutOfBandTextTrackPrivateAVF*>(textTrack.get());
+        RetainPtr<AVMediaSelectionOptionType> currentOption = trackPrivate->mediaSelectionOption();
+        
+        for (auto& track : outOfBandTrackSources) {
+            RetainPtr<CFStringRef> uniqueID = String::number(track->uniqueId()).createCFString();
+            
+            if (![[currentOption.get() outOfBandIdentifier] isEqual: reinterpret_cast<const NSString*>(uniqueID.get())])
+                continue;
+            
+            InbandTextTrackPrivate::Mode mode = InbandTextTrackPrivate::Hidden;
+            if (track->mode() == PlatformTextTrack::Hidden)
+                mode = InbandTextTrackPrivate::Hidden;
+            else if (track->mode() == PlatformTextTrack::Disabled)
+                mode = InbandTextTrackPrivate::Disabled;
+            else if (track->mode() == PlatformTextTrack::Showing)
+                mode = InbandTextTrackPrivate::Showing;
+            
+            textTrack->setMode(mode);
+            break;
+        }
+    }
+}
 #endif
 
 void MediaPlayerPrivateAVFoundationObjC::createAVAssetForURL(const String& url)
@@ -1745,7 +1783,7 @@ void MediaPlayerPrivateAVFoundationObjC::processLegacyClosedCaptionsTracks()
 
         bool newCCTrack = true;
         for (unsigned i = removedTextTracks.size(); i > 0; --i) {
-            if (!removedTextTracks[i - 1]->isLegacyClosedCaptionsTrack())
+            if (removedTextTracks[i - 1]->textTrackCategory() != InbandTextTrackPrivateAVF::LegacyClosedCaption)
                 continue;
 
             RefPtr<InbandTextTrackPrivateLegacyAVFObjC> track = static_cast<InbandTextTrackPrivateLegacyAVFObjC*>(m_textTracks[i - 1].get());
@@ -1796,11 +1834,22 @@ void MediaPlayerPrivateAVFoundationObjC::processMediaSelectionOptions()
     for (AVMediaSelectionOptionType *option in legibleOptions) {
         bool newTrack = true;
         for (unsigned i = removedTextTracks.size(); i > 0; --i) {
-             if (removedTextTracks[i - 1]->isLegacyClosedCaptionsTrack())
-                 continue;
-
-            RefPtr<InbandTextTrackPrivateAVFObjC> track = static_cast<InbandTextTrackPrivateAVFObjC*>(removedTextTracks[i - 1].get());
-            if ([track->mediaSelectionOption() isEqual:option]) {
+            if (removedTextTracks[i - 1]->textTrackCategory() == InbandTextTrackPrivateAVF::LegacyClosedCaption)
+                continue;
+            
+            RetainPtr<AVMediaSelectionOptionType> currentOption;
+#if ENABLE(AVF_CAPTIONS)
+            if (removedTextTracks[i - 1]->textTrackCategory() == InbandTextTrackPrivateAVF::OutOfBand) {
+                RefPtr<OutOfBandTextTrackPrivateAVF> track = static_cast<OutOfBandTextTrackPrivateAVF*>(removedTextTracks[i - 1].get());
+                currentOption = track->mediaSelectionOption();
+            } else
+#endif
+            {
+                RefPtr<InbandTextTrackPrivateAVFObjC> track = static_cast<InbandTextTrackPrivateAVFObjC*>(removedTextTracks[i - 1].get());
+                currentOption = track->mediaSelectionOption();
+            }
+            
+            if ([currentOption.get() isEqual:option]) {
                 removedTextTracks.remove(i - 1);
                 newTrack = false;
                 break;
@@ -1810,9 +1859,11 @@ void MediaPlayerPrivateAVFoundationObjC::processMediaSelectionOptions()
             continue;
 
 #if ENABLE(AVF_CAPTIONS)
-        // Ignore out-of-band tracks that we passed to AVFoundation so we do not double-count them
-        if ([option outOfBandSource])
+        if ([option outOfBandSource]) {
+            m_textTracks.append(OutOfBandTextTrackPrivateAVF::create(this, option));
+            m_textTracks.last()->setHasBeenReported(true); // Ignore out-of-band tracks that we passed to AVFoundation so we do not double-count them
             continue;
+        }
 #endif
 
         m_textTracks.append(InbandTextTrackPrivateAVFObjC::create(this, option));
@@ -1850,9 +1901,13 @@ void MediaPlayerPrivateAVFoundationObjC::setCurrentTrack(InbandTextTrackPrivateA
     m_currentTrack = track;
 
     if (track) {
-        if (track->isLegacyClosedCaptionsTrack())
+        if (track->textTrackCategory() == InbandTextTrackPrivateAVF::LegacyClosedCaption)
             [m_avPlayer.get() setClosedCaptionDisplayEnabled:YES];
 #if HAVE(AVFOUNDATION_MEDIA_SELECTION_GROUP)
+#if ENABLE(AVF_CAPTIONS)
+        else if (track->textTrackCategory() == InbandTextTrackPrivateAVF::OutOfBand)
+            [m_avPlayerItem.get() selectMediaOption:static_cast<OutOfBandTextTrackPrivateAVF*>(track)->mediaSelectionOption() inMediaSelectionGroup:safeMediaSelectionGroupForLegibleMedia()];
+#endif
         else
             [m_avPlayerItem.get() selectMediaOption:static_cast<InbandTextTrackPrivateAVFObjC*>(track)->mediaSelectionOption() inMediaSelectionGroup:safeMediaSelectionGroupForLegibleMedia()];
 #endif
diff --git a/Source/WebCore/platform/graphics/avfoundation/objc/OutOfBandTextTrackPrivateAVF.h b/Source/WebCore/platform/graphics/avfoundation/objc/OutOfBandTextTrackPrivateAVF.h
new file mode 100644 (file)
index 0000000..ff45b21
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef OutOfBandTextTrackPrivateAVF_h
+#define OutOfBandTextTrackPrivateAVF_h
+
+#if ENABLE(VIDEO) && (USE(AVFOUNDATION) || PLATFORM(IOS)) && ENABLE(AVF_CAPTIONS)
+
+#include "InbandTextTrackPrivateAVF.h"
+
+OBJC_CLASS AVMediaSelectionOption;
+
+namespace WebCore {
+    
+class OutOfBandTextTrackPrivateAVF : public InbandTextTrackPrivateAVF {
+public:
+    static PassRefPtr<OutOfBandTextTrackPrivateAVF> create(AVFInbandTrackParent* player,  AVMediaSelectionOption* selection)
+    {
+        return adoptRef(new OutOfBandTextTrackPrivateAVF(player, selection));
+    }
+    
+    virtual void processCue(CFArrayRef, double) override { }
+    virtual void resetCueValues() override { }
+    
+    virtual Category textTrackCategory() const override { return OutOfBand; }
+    
+    AVMediaSelectionOption* mediaSelectionOption() const { return m_mediaSelectionOption.get(); }
+    
+protected:
+    OutOfBandTextTrackPrivateAVF(AVFInbandTrackParent* player, AVMediaSelectionOption* selection)
+        : InbandTextTrackPrivateAVF(player)
+        , m_mediaSelectionOption(selection)
+    {
+    }
+    
+    RetainPtr<AVMediaSelectionOption> m_mediaSelectionOption;
+};
+    
+}
+
+#endif
+
+#endif // OutOfBandTextTrackPrivateAVF_h
index 704f564..b9a9682 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -45,7 +45,7 @@ public:
     virtual InbandTextTrackPrivate::Kind kind() const override;
     virtual AtomicString label() const override { return m_name; }
     virtual AtomicString language() const override { return m_language; }
-    virtual bool isLegacyClosedCaptionsTrack() const override { return false; }
+    virtual Category textTrackCategory() const override { return InBand; }
     int internalID() const { return m_internalID; }
 
 protected:
index a5ac631..f1c078c 100644 (file)
@@ -984,7 +984,7 @@ void MediaPlayerPrivateIOS::setSelectedTextTrack(NSNumber *trackID)
 
     setDelayCallbacks(true);
     {
-        LOG(Media, "MediaPlayerPrivateIOS::setCurrentTrack(%p) - selecting track id %i", this, [trackID intValue]);
+        LOG(Media, "MediaPlayerPrivateIOS::setSelectedTextTrack(%p) - selecting track id %i", this, [trackID intValue]);
         [m_deferredProperties.get() removeObjectForKey:DeferredPropertySelectedTrackKey];
         [m_mediaPlayerHelper.get() _setSelectedTextTrack:trackID];
     }