1/*
2 * Copyright (C) 2011-2014 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef MediaPlayerPrivateAVFoundation_h
27#define MediaPlayerPrivateAVFoundation_h
28
29#if ENABLE(VIDEO) && USE(AVFOUNDATION)
30
31#include "FloatSize.h"
32#include "InbandTextTrackPrivateAVF.h"
33#include "MediaPlayerPrivate.h"
34#include "Timer.h"
35#include <functional>
36#include <wtf/Functional.h>
37#include <wtf/RetainPtr.h>
38#include <wtf/WeakPtr.h>
39
40namespace WebCore {
41
42class InbandMetadataTextTrackPrivateAVF;
43class InbandTextTrackPrivateAVF;
44class GenericCueData;
45
46class MediaPlayerPrivateAVFoundation : public MediaPlayerPrivateInterface, public AVFInbandTrackParent
47{
48public:
49
50    virtual void repaint();
51    virtual void metadataLoaded();
52    virtual void playabilityKnown();
53    virtual void rateChanged();
54    virtual void loadedTimeRangesChanged();
55    virtual void seekableTimeRangesChanged();
56    virtual void timeChanged(double);
57    virtual void seekCompleted(bool);
58    virtual void didEnd();
59    virtual void contentsNeedsDisplay() { }
60    virtual void configureInbandTracks();
61    virtual void setCurrentTextTrack(InbandTextTrackPrivateAVF*) { }
62    virtual InbandTextTrackPrivateAVF* currentTextTrack() const = 0;
63#if ENABLE(IOS_AIRPLAY)
64    void playbackTargetIsWirelessChanged();
65#endif
66
67    class Notification {
68    public:
69#define FOR_EACH_MEDIAPLAYERPRIVATEAVFOUNDATION_NOTIFICATION_TYPE(macro) \
70    macro(None) \
71    macro(ItemDidPlayToEndTime) \
72    macro(ItemTracksChanged) \
73    macro(ItemStatusChanged) \
74    macro(ItemSeekableTimeRangesChanged) \
75    macro(ItemLoadedTimeRangesChanged) \
76    macro(ItemPresentationSizeChanged) \
77    macro(ItemIsPlaybackLikelyToKeepUpChanged) \
78    macro(ItemIsPlaybackBufferEmptyChanged) \
79    macro(ItemIsPlaybackBufferFullChanged) \
80    macro(AssetMetadataLoaded) \
81    macro(AssetPlayabilityKnown) \
82    macro(PlayerRateChanged) \
83    macro(PlayerTimeChanged) \
84    macro(SeekCompleted) \
85    macro(DurationChanged) \
86    macro(ContentsNeedsDisplay) \
87    macro(InbandTracksNeedConfiguration) \
88    macro(TargetIsWirelessChanged) \
89
90        enum Type {
91#define DEFINE_TYPE_ENUM(type) type,
92            FOR_EACH_MEDIAPLAYERPRIVATEAVFOUNDATION_NOTIFICATION_TYPE(DEFINE_TYPE_ENUM)
93#undef DEFINE_TYPE_ENUM
94            FunctionType,
95        };
96
97        Notification()
98            : m_type(None)
99            , m_time(0)
100            , m_finished(false)
101        {
102        }
103
104        Notification(Type type, double time)
105            : m_type(type)
106            , m_time(time)
107            , m_finished(false)
108        {
109        }
110
111        Notification(Type type, bool finished)
112            : m_type(type)
113            , m_time(0)
114            , m_finished(finished)
115        {
116        }
117
118        Notification(std::function<void ()> function)
119            : m_type(FunctionType)
120            , m_time(0)
121            , m_finished(false)
122            , m_function(function)
123        {
124        }
125
126        Type type() { return m_type; }
127        bool isValid() { return m_type != None; }
128        double time() { return m_time; }
129        bool finished() { return m_finished; }
130        std::function<void ()>& function() { return m_function; }
131
132    private:
133        Type m_type;
134        double m_time;
135        bool m_finished;
136        std::function<void ()> m_function;
137    };
138
139    void scheduleMainThreadNotification(Notification);
140    void scheduleMainThreadNotification(Notification::Type, double time = 0);
141    void scheduleMainThreadNotification(Notification::Type, bool completed);
142    void dispatchNotification();
143    void clearMainThreadPendingFlag();
144
145#if ENABLE(ENCRYPTED_MEDIA) || ENABLE(ENCRYPTED_MEDIA_V2)
146    static bool extractKeyURIKeyIDAndCertificateFromInitData(Uint8Array* initData, String& keyURI, String& keyID, RefPtr<Uint8Array>& certificate);
147#endif
148
149protected:
150    MediaPlayerPrivateAVFoundation(MediaPlayer*);
151    virtual ~MediaPlayerPrivateAVFoundation();
152
153    WeakPtr<MediaPlayerPrivateAVFoundation> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
154
155    // MediaPlayerPrivatePrivateInterface overrides.
156    virtual void load(const String& url) override;
157#if ENABLE(MEDIA_SOURCE)
158    virtual void load(const String&, MediaSourcePrivateClient*);
159#endif
160    virtual void cancelLoad() = 0;
161
162    virtual void prepareToPlay() override;
163    virtual PlatformMedia platformMedia() const = 0;
164
165    virtual void play() override;
166    virtual void pause() override;
167
168    virtual IntSize naturalSize() const override;
169    virtual bool hasVideo() const override { return m_cachedHasVideo; }
170    virtual bool hasAudio() const override { return m_cachedHasAudio; }
171    virtual void setVisible(bool) override;
172    virtual float duration() const override;
173    virtual double durationDouble() const override;
174    virtual float currentTime() const override;
175    virtual double currentTimeDouble() const = 0;
176    virtual void seek(float) override;
177    virtual void seekWithTolerance(double, double, double) override;
178    virtual bool seeking() const override;
179    virtual void setRate(float) override;
180    virtual bool paused() const override;
181    virtual void setVolume(float) = 0;
182    virtual bool hasClosedCaptions() const override { return m_cachedHasCaptions; }
183    virtual void setClosedCaptionsVisible(bool) = 0;
184    virtual MediaPlayer::NetworkState networkState() const override { return m_networkState; }
185    virtual MediaPlayer::ReadyState readyState() const override { return m_readyState; }
186    virtual double maxTimeSeekableDouble() const override;
187    virtual double minTimeSeekable() const override;
188    virtual std::unique_ptr<PlatformTimeRanges> buffered() const override;
189    virtual bool didLoadingProgress() const override;
190    virtual void setSize(const IntSize&) override;
191    virtual void paint(GraphicsContext*, const IntRect&) = 0;
192    virtual void paintCurrentFrameInContext(GraphicsContext*, const IntRect&) = 0;
193    virtual void setPreload(MediaPlayer::Preload) override;
194    virtual PlatformLayer* platformLayer() const { return 0; }
195    virtual bool supportsAcceleratedRendering() const = 0;
196    virtual void acceleratedRenderingStateChanged() override;
197    virtual bool shouldMaintainAspectRatio() const override { return m_shouldMaintainAspectRatio; }
198    virtual void setShouldMaintainAspectRatio(bool) override;
199
200    virtual MediaPlayer::MovieLoadType movieLoadType() const;
201    virtual void prepareForRendering();
202    virtual float mediaTimeForTimeValue(float) const = 0;
203
204    virtual bool supportsFullscreen() const;
205    virtual bool supportsScanning() const { return true; }
206    unsigned long long fileSize() const { return totalBytes(); }
207
208    // Required interfaces for concrete derived classes.
209    virtual void createAVAssetForURL(const String&) = 0;
210    virtual void createAVPlayer() = 0;
211    virtual void createAVPlayerItem() = 0;
212
213    enum ItemStatus {
214        MediaPlayerAVPlayerItemStatusDoesNotExist,
215        MediaPlayerAVPlayerItemStatusUnknown,
216        MediaPlayerAVPlayerItemStatusFailed,
217        MediaPlayerAVPlayerItemStatusReadyToPlay,
218        MediaPlayerAVPlayerItemStatusPlaybackBufferEmpty,
219        MediaPlayerAVPlayerItemStatusPlaybackBufferFull,
220        MediaPlayerAVPlayerItemStatusPlaybackLikelyToKeepUp,
221    };
222    virtual ItemStatus playerItemStatus() const = 0;
223
224    enum AssetStatus {
225        MediaPlayerAVAssetStatusDoesNotExist,
226        MediaPlayerAVAssetStatusUnknown,
227        MediaPlayerAVAssetStatusLoading,
228        MediaPlayerAVAssetStatusFailed,
229        MediaPlayerAVAssetStatusCancelled,
230        MediaPlayerAVAssetStatusLoaded,
231        MediaPlayerAVAssetStatusPlayable,
232    };
233    virtual AssetStatus assetStatus() const = 0;
234
235    virtual void platformSetVisible(bool) = 0;
236    virtual void platformPlay() = 0;
237    virtual void platformPause() = 0;
238    virtual void checkPlayability() = 0;
239    virtual void updateRate() = 0;
240    virtual float rate() const = 0;
241    virtual void seekToTime(double time, double negativeTolerance, double positiveTolerance) = 0;
242    virtual unsigned long long totalBytes() const = 0;
243    virtual std::unique_ptr<PlatformTimeRanges> platformBufferedTimeRanges() const = 0;
244    virtual double platformMaxTimeSeekable() const = 0;
245    virtual double platformMinTimeSeekable() const = 0;
246    virtual float platformMaxTimeLoaded() const = 0;
247    virtual double platformDuration() const = 0;
248
249    virtual void beginLoadingMetadata() = 0;
250    virtual void tracksChanged() = 0;
251    virtual void sizeChanged() = 0;
252
253    virtual void createContextVideoRenderer() = 0;
254    virtual void destroyContextVideoRenderer() = 0;
255
256    virtual void createVideoLayer() = 0;
257    virtual void destroyVideoLayer() = 0;
258
259    virtual bool hasAvailableVideoFrame() const = 0;
260
261    virtual bool hasContextRenderer() const = 0;
262    virtual bool hasLayerRenderer() const = 0;
263
264    virtual void updateVideoLayerGravity() = 0;
265
266protected:
267    void updateStates();
268
269    void setHasVideo(bool);
270    void setHasAudio(bool);
271    void setHasClosedCaptions(bool);
272    void characteristicsChanged();
273    void setDelayCharacteristicsChangedNotification(bool);
274    void setDelayCallbacks(bool) const;
275    void setIgnoreLoadStateChanges(bool delay) { m_ignoreLoadStateChanges = delay; }
276    void setNaturalSize(IntSize);
277    bool isLiveStream() const { return std::isinf(duration()); }
278
279    enum MediaRenderingMode { MediaRenderingNone, MediaRenderingToContext, MediaRenderingToLayer };
280    MediaRenderingMode currentRenderingMode() const;
281    MediaRenderingMode preferredRenderingMode() const;
282
283    bool metaDataAvailable() const { return m_readyState >= MediaPlayer::HaveMetadata; }
284    float requestedRate() const { return m_requestedRate; }
285    float maxTimeLoaded() const;
286    bool isReadyForVideoSetup() const;
287    virtual void setUpVideoRendering();
288    virtual void tearDownVideoRendering();
289    bool hasSetUpVideoRendering() const;
290
291    static void mainThreadCallback(void*);
292
293    void invalidateCachedDuration();
294
295    const String& assetURL() const { return m_assetURL; }
296
297    MediaPlayer* player() { return m_player; }
298
299    virtual String engineDescription() const { return "AVFoundation"; }
300
301    virtual size_t extraMemoryCost() const override;
302
303    virtual void trackModeChanged() override;
304#if ENABLE(AVF_CAPTIONS)
305    virtual void notifyTrackModeChanged() { }
306    virtual void synchronizeTextTrackState() { }
307#endif
308    void processNewAndRemovedTextTracks(const Vector<RefPtr<InbandTextTrackPrivateAVF>>&);
309    void clearTextTracks();
310    Vector<RefPtr<InbandTextTrackPrivateAVF>> m_textTracks;
311
312private:
313    MediaPlayer* m_player;
314
315    WeakPtrFactory<MediaPlayerPrivateAVFoundation> m_weakPtrFactory;
316
317    std::function<void()> m_pendingSeek;
318
319    Vector<Notification> m_queuedNotifications;
320    mutable Mutex m_queueMutex;
321
322    mutable std::unique_ptr<PlatformTimeRanges> m_cachedLoadedTimeRanges;
323
324    MediaPlayer::NetworkState m_networkState;
325    MediaPlayer::ReadyState m_readyState;
326
327    String m_assetURL;
328    MediaPlayer::Preload m_preload;
329
330    IntSize m_cachedNaturalSize;
331    mutable float m_cachedMaxTimeLoaded;
332    mutable double m_cachedMaxTimeSeekable;
333    mutable double m_cachedMinTimeSeekable;
334    mutable double m_cachedDuration;
335    float m_reportedDuration;
336    mutable float m_maxTimeLoadedAtLastDidLoadingProgress;
337    float m_requestedRate;
338    mutable int m_delayCallbacks;
339    int m_delayCharacteristicsChangedNotification;
340    bool m_mainThreadCallPending;
341    bool m_assetIsPlayable;
342    bool m_visible;
343    bool m_loadingMetadata;
344    bool m_isAllowedToRender;
345    bool m_cachedHasAudio;
346    bool m_cachedHasVideo;
347    bool m_cachedHasCaptions;
348    bool m_ignoreLoadStateChanges;
349    bool m_haveReportedFirstVideoFrame;
350    bool m_playWhenFramesAvailable;
351    bool m_inbandTrackConfigurationPending;
352    bool m_characteristicsChanged;
353    bool m_shouldMaintainAspectRatio;
354    bool m_seeking;
355};
356
357} // namespace WebCore
358
359#endif // ENABLE(VIDEO) && USE(AVFOUNDATION)
360
361#endif // MediaPlayerPrivateAVFoundation_h
362