e1394816652bf17109f00b0ed22ae8abdebc6d1d
[WebKit-https.git] / Source / WebCore / platform / graphics / cocoa / WebCoreDecompressionSession.h
1 /*
2  * Copyright (C) 2017 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. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #if USE(VIDEOTOOLBOX)
29
30 #include <CoreMedia/CMTime.h>
31 #include <functional>
32 #include <wtf/Lock.h>
33 #include <wtf/MediaTime.h>
34 #include <wtf/OSObjectPtr.h>
35 #include <wtf/Ref.h>
36 #include <wtf/RetainPtr.h>
37 #include <wtf/ThreadSafeRefCounted.h>
38
39 typedef CFTypeRef CMBufferRef;
40 typedef const struct __CFArray * CFArrayRef;
41 typedef struct opaqueCMBufferQueue *CMBufferQueueRef;
42 typedef struct opaqueCMSampleBuffer *CMSampleBufferRef;
43 typedef struct OpaqueCMTimebase* CMTimebaseRef;
44 typedef signed long CMItemCount;
45 typedef struct __CVBuffer *CVPixelBufferRef;
46 typedef struct __CVBuffer *CVImageBufferRef;
47 typedef UInt32 VTDecodeInfoFlags;
48 typedef UInt32 VTDecodeInfoFlags;
49 typedef struct OpaqueVTDecompressionSession*  VTDecompressionSessionRef;
50
51 namespace WebCore {
52
53 class WebCoreDecompressionSession : public ThreadSafeRefCounted<WebCoreDecompressionSession> {
54 public:
55     static Ref<WebCoreDecompressionSession> createOpenGL() { return adoptRef(*new WebCoreDecompressionSession(OpenGL)); }
56     static Ref<WebCoreDecompressionSession> createRGB() { return adoptRef(*new WebCoreDecompressionSession(RGB)); }
57
58     void invalidate();
59     bool isInvalidated() const { return m_invalidated; }
60
61     void enqueueSample(CMSampleBufferRef, bool displaying = true);
62     bool isReadyForMoreMediaData() const;
63     void requestMediaDataWhenReady(std::function<void()>);
64     void stopRequestingMediaData();
65     void notifyWhenHasAvailableVideoFrame(std::function<void()>);
66
67     RetainPtr<CVPixelBufferRef> decodeSampleSync(CMSampleBufferRef);
68
69     void setTimebase(CMTimebaseRef);
70     CMTimebaseRef timebase() const { return m_timebase.get(); }
71
72     enum ImageForTimeFlags { ExactTime, AllowEarlier, AllowLater };
73     RetainPtr<CVPixelBufferRef> imageForTime(const MediaTime&, ImageForTimeFlags = ExactTime);
74     void flush();
75
76     unsigned totalVideoFrames() const { return m_totalVideoFrames; }
77     unsigned droppedVideoFrames() const { return m_droppedVideoFrames; }
78     unsigned corruptedVideoFrames() const { return m_corruptedVideoFrames; }
79     MediaTime totalFrameDelay() const { return m_totalFrameDelay; }
80
81 private:
82     enum Mode {
83         OpenGL,
84         RGB,
85     };
86     WebCoreDecompressionSession(Mode);
87
88     void ensureDecompressionSessionForSample(CMSampleBufferRef);
89
90     void decodeSample(CMSampleBufferRef, bool displaying);
91     void enqueueDecodedSample(CMSampleBufferRef, bool displaying);
92     void handleDecompressionOutput(bool displaying, OSStatus, VTDecodeInfoFlags, CVImageBufferRef, CMTime presentationTimeStamp, CMTime presentationDuration);
93     RetainPtr<CVPixelBufferRef> getFirstVideoFrame();
94     void resetAutomaticDequeueTimer();
95     void automaticDequeue();
96     bool shouldDecodeSample(CMSampleBufferRef, bool displaying);
97
98     static CMTime getDecodeTime(CMBufferRef, void* refcon);
99     static CMTime getPresentationTime(CMBufferRef, void* refcon);
100     static CMTime getDuration(CMBufferRef, void* refcon);
101     static CFComparisonResult compareBuffers(CMBufferRef buf1, CMBufferRef buf2, void* refcon);
102     void maybeBecomeReadyForMoreMediaData();
103
104     void resetQosTier();
105     void increaseQosTier();
106     void decreaseQosTier();
107     void updateQosWithDecodeTimeStatistics(double ratio);
108
109     static const CMItemCount kMaximumCapacity = 120;
110     static const CMItemCount kHighWaterMark = 60;
111     static const CMItemCount kLowWaterMark = 15;
112
113     Mode m_mode;
114     RetainPtr<VTDecompressionSessionRef> m_decompressionSession;
115     RetainPtr<CMBufferQueueRef> m_producerQueue;
116     RetainPtr<CMBufferQueueRef> m_consumerQueue;
117     RetainPtr<CMTimebaseRef> m_timebase;
118     OSObjectPtr<dispatch_queue_t> m_decompressionQueue;
119     OSObjectPtr<dispatch_queue_t> m_enqueingQueue;
120     OSObjectPtr<dispatch_semaphore_t> m_hasAvailableImageSemaphore;
121     OSObjectPtr<dispatch_source_t> m_timerSource;
122     std::function<void()> m_notificationCallback;
123     std::function<void()> m_hasAvailableFrameCallback;
124     RetainPtr<CFArrayRef> m_qosTiers;
125     int m_currentQosTier { 0 };
126     unsigned m_framesSinceLastQosCheck { 0 };
127     double m_decodeRatioMovingAverage { 0 };
128
129     bool m_invalidated { false };
130     int m_framesBeingDecoded { 0 };
131     unsigned m_totalVideoFrames { 0 };
132     unsigned m_droppedVideoFrames { 0 };
133     unsigned m_corruptedVideoFrames { 0 };
134     MediaTime m_totalFrameDelay;
135 };
136
137 }
138
139 #endif