c56b50bf59bafd4b08e929023740eb886134cdfb
[WebKit-https.git] / Source / WebCore / platform / graphics / avfoundation / objc / MediaSourcePrivateAVFObjC.mm
1 /*
2  * Copyright (C) 2013 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 COMPUTER, 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 COMPUTER, 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 #include "config.h"
27 #include "MediaSourcePrivateAVFObjC.h"
28
29 #if ENABLE(MEDIA_SOURCE) && USE(AVFOUNDATION)
30
31 #import "ContentType.h"
32 #import "ExceptionCodePlaceholder.h"
33 #import "MediaPlayerPrivateMediaSourceAVFObjC.h"
34 #import "SourceBufferPrivateAVFObjC.h"
35 #import "NotImplemented.h"
36 #import "SoftLinking.h"
37 #import <objc/runtime.h>
38 #import <wtf/text/AtomicString.h>
39 #import <wtf/text/StringBuilder.h>
40
41 namespace WebCore {
42
43 #pragma mark -
44 #pragma mark MediaSourcePrivateAVFObjC
45
46 RefPtr<MediaSourcePrivateAVFObjC> MediaSourcePrivateAVFObjC::create(MediaPlayerPrivateMediaSourceAVFObjC* parent)
47 {
48     return adoptRef(new MediaSourcePrivateAVFObjC(parent));
49 }
50
51 MediaSourcePrivateAVFObjC::MediaSourcePrivateAVFObjC(MediaPlayerPrivateMediaSourceAVFObjC* parent)
52     : m_player(parent)
53     , m_duration(std::numeric_limits<double>::quiet_NaN())
54     , m_isEnded(false)
55 {
56 }
57
58 MediaSourcePrivateAVFObjC::~MediaSourcePrivateAVFObjC()
59 {
60 }
61
62 MediaSourcePrivate::AddStatus MediaSourcePrivateAVFObjC::addSourceBuffer(const ContentType& contentType, RefPtr<SourceBufferPrivate>& outPrivate)
63 {
64     MediaEngineSupportParameters parameters;
65     parameters.isMediaSource = true;
66     parameters.type = contentType.type();
67     parameters.codecs = contentType.parameter(ASCIILiteral("codecs"));
68     if (MediaPlayerPrivateMediaSourceAVFObjC::supportsType(parameters) == MediaPlayer::IsNotSupported)
69         return NotSupported;
70
71     m_sourceBuffers.append(SourceBufferPrivateAVFObjC::create(this));
72     outPrivate = m_sourceBuffers.last();
73
74     return Ok;
75 }
76
77 void MediaSourcePrivateAVFObjC::removeSourceBuffer(SourceBufferPrivate* buffer)
78 {
79     ASSERT(m_sourceBuffers.contains(buffer));
80
81     size_t pos = m_activeSourceBuffers.find(buffer);
82     if (pos != notFound)
83         m_activeSourceBuffers.remove(pos);
84
85     pos = m_sourceBuffers.find(buffer);
86     m_sourceBuffers.remove(pos);
87 }
88
89 double MediaSourcePrivateAVFObjC::duration()
90 {
91     return m_duration;
92 }
93
94 void MediaSourcePrivateAVFObjC::setDuration(double duration)
95 {
96     if (duration == m_duration)
97         return;
98
99     m_duration = duration;
100 }
101
102 void MediaSourcePrivateAVFObjC::markEndOfStream(EndOfStreamStatus) 
103 {
104     // FIXME(125159): implement markEndOfStream()
105     m_isEnded = true;
106 }
107
108 void MediaSourcePrivateAVFObjC::unmarkEndOfStream() 
109 {
110     // FIXME(125159): implement unmarkEndOfStream()
111     m_isEnded = false;
112 }
113
114 MediaPlayer::ReadyState MediaSourcePrivateAVFObjC::readyState() const
115 {
116     return m_player->readyState();
117 }
118
119 void MediaSourcePrivateAVFObjC::setReadyState(MediaPlayer::ReadyState readyState)
120 {
121     m_player->setReadyState(readyState);
122 }
123
124 void MediaSourcePrivateAVFObjC::sourceBufferPrivateDidChangeActiveState(SourceBufferPrivateAVFObjC* buffer, bool active)
125 {
126     if (active && !m_activeSourceBuffers.contains(buffer))
127         m_activeSourceBuffers.append(buffer);
128
129     if (!active) {
130         size_t position = m_activeSourceBuffers.find(buffer);
131         if (position != notFound)
132             m_activeSourceBuffers.remove(position);
133     }
134 }
135
136 static bool MediaSourcePrivateAVFObjCHasAudio(PassRefPtr<SourceBufferPrivateAVFObjC> prpSourceBuffer)
137 {
138     RefPtr<SourceBufferPrivateAVFObjC> sourceBuffer = prpSourceBuffer;
139     return sourceBuffer->hasAudio();
140 }
141
142 bool MediaSourcePrivateAVFObjC::hasAudio() const
143 {
144     return std::any_of(m_activeSourceBuffers.begin(), m_activeSourceBuffers.end(), MediaSourcePrivateAVFObjCHasAudio);
145 }
146
147 static bool MediaSourcePrivateAVFObjCHasVideo(PassRefPtr<SourceBufferPrivateAVFObjC> prpSourceBuffer)
148 {
149     RefPtr<SourceBufferPrivateAVFObjC> sourceBuffer = prpSourceBuffer;
150     return sourceBuffer->hasVideo();
151 }
152
153 bool MediaSourcePrivateAVFObjC::hasVideo() const
154 {
155     return std::any_of(m_activeSourceBuffers.begin(), m_activeSourceBuffers.end(), MediaSourcePrivateAVFObjCHasVideo);
156 }
157
158 MediaTime MediaSourcePrivateAVFObjC::seekToTime(MediaTime targetTime, MediaTime negativeThreshold, MediaTime positiveThreshold)
159 {
160     MediaTime seekTime = targetTime;
161     for (auto it = m_activeSourceBuffers.begin(), end = m_activeSourceBuffers.end(); it != end; ++it) {
162         MediaTime sourceSeekTime = (*it)->fastSeekTimeForMediaTime(targetTime, negativeThreshold, positiveThreshold);
163         if (abs(targetTime - sourceSeekTime) > abs(targetTime - seekTime))
164             seekTime = sourceSeekTime;
165     }
166
167     for (auto it = m_activeSourceBuffers.begin(), end = m_activeSourceBuffers.end(); it != end; ++it)
168         (*it)->seekToTime(seekTime);
169
170     return seekTime;
171 }
172
173 }
174
175 #endif // ENABLE(MEDIA_SOURCE) && USE(AVFOUNDATION)