b49d1f6fb2148e50be42afebaa5ff0aebeb67cd1
[WebKit-https.git] / Source / WebCore / platform / mediastream / mac / RealtimeMediaSourceCenterMac.cpp
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  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer
12  *    in the documentation and/or other materials provided with the
13  *    distribution.
14  * 3. Neither the name of Ericsson nor the names of its contributors
15  *    may be used to endorse or promote products derived from this
16  *    software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32
33 #if ENABLE(MEDIA_STREAM)
34 #include "RealtimeMediaSourceCenterMac.h"
35
36 #include "AVCaptureDeviceManager.h"
37 #include "MediaStreamCreationClient.h"
38 #include "MediaStreamPrivate.h"
39 #include "MediaStreamTrackSourcesRequestClient.h"
40 #include <wtf/MainThread.h>
41
42 namespace WebCore {
43
44 RealtimeMediaSourceCenter& RealtimeMediaSourceCenter::platformCenter()
45 {
46     ASSERT(isMainThread());
47     DEPRECATED_DEFINE_STATIC_LOCAL(RealtimeMediaSourceCenterMac, center, ());
48     return center;
49 }
50
51 RealtimeMediaSourceCenterMac::RealtimeMediaSourceCenterMac()
52 {
53     m_supportedConstraints.setSupportsWidth(true);
54     m_supportedConstraints.setSupportsHeight(true);
55     m_supportedConstraints.setSupportsAspectRatio(true);
56     m_supportedConstraints.setSupportsFrameRate(true);
57     m_supportedConstraints.setSupportsFacingMode(true);
58     m_supportedConstraints.setSupportsVolume(true);
59     m_supportedConstraints.setSupportsSampleRate(false);
60     m_supportedConstraints.setSupportsSampleSize(false);
61     m_supportedConstraints.setSupportsEchoCancellation(false);
62     m_supportedConstraints.setSupportsDeviceId(true);
63     m_supportedConstraints.setSupportsGroupId(true);
64 }
65
66 RealtimeMediaSourceCenterMac::~RealtimeMediaSourceCenterMac()
67 {
68 }
69
70 void RealtimeMediaSourceCenterMac::validateRequestConstraints(MediaStreamCreationClient* client, RefPtr<MediaConstraints>& audioConstraints, RefPtr<MediaConstraints>& videoConstraints)
71 {
72     ASSERT(client);
73
74     Vector<RefPtr<RealtimeMediaSource>> audioSources;
75     Vector<RefPtr<RealtimeMediaSource>> videoSources;
76
77     if (audioConstraints) {
78         String invalidConstraint;
79         AVCaptureDeviceManager::singleton().verifyConstraintsForMediaType(RealtimeMediaSource::Audio, audioConstraints.get(), nullptr, invalidConstraint);
80         if (!invalidConstraint.isEmpty()) {
81             client->constraintsInvalid(invalidConstraint);
82             return;
83         }
84
85         audioSources = AVCaptureDeviceManager::singleton().bestSourcesForTypeAndConstraints(RealtimeMediaSource::Type::Audio, audioConstraints);
86     }
87
88     if (videoConstraints) {
89         String invalidConstraint;
90         AVCaptureDeviceManager::singleton().verifyConstraintsForMediaType(RealtimeMediaSource::Video, videoConstraints.get(), nullptr, invalidConstraint);
91         if (!invalidConstraint.isEmpty()) {
92             client->constraintsInvalid(invalidConstraint);
93             return;
94         }
95
96         videoSources = AVCaptureDeviceManager::singleton().bestSourcesForTypeAndConstraints(RealtimeMediaSource::Type::Video, videoConstraints);
97     }
98     client->constraintsValidated(audioSources, videoSources);
99 }
100
101 void RealtimeMediaSourceCenterMac::createMediaStream(PassRefPtr<MediaStreamCreationClient> prpQueryClient, PassRefPtr<MediaConstraints> audioConstraints, PassRefPtr<MediaConstraints> videoConstraints)
102 {
103     RefPtr<MediaStreamCreationClient> client = prpQueryClient;
104     
105     ASSERT(client);
106     
107     Vector<RefPtr<RealtimeMediaSource>> audioSources;
108     Vector<RefPtr<RealtimeMediaSource>> videoSources;
109     
110     if (audioConstraints) {
111         String invalidConstraint;
112         AVCaptureDeviceManager::singleton().verifyConstraintsForMediaType(RealtimeMediaSource::Audio, audioConstraints.get(), nullptr, invalidConstraint);
113         if (!invalidConstraint.isEmpty()) {
114             client->failedToCreateStreamWithConstraintsError(invalidConstraint);
115             return;
116         }
117         // FIXME: Consider the constraints when choosing among multiple devices. For now just select the first available
118         // device of the appropriate type.
119         RefPtr<RealtimeMediaSource> audioSource = AVCaptureDeviceManager::singleton().bestSourcesForTypeAndConstraints(RealtimeMediaSource::Audio, audioConstraints.get()).at(0);
120         ASSERT(audioSource);
121         
122         audioSources.append(audioSource.release());
123     }
124     
125     if (videoConstraints) {
126         String invalidConstraint;
127         AVCaptureDeviceManager::singleton().verifyConstraintsForMediaType(RealtimeMediaSource::Video, videoConstraints.get(), nullptr, invalidConstraint);
128         if (!invalidConstraint.isEmpty()) {
129             client->failedToCreateStreamWithConstraintsError(invalidConstraint);
130             return;
131         }
132         // FIXME: Consider the constraints when choosing among multiple devices. For now just select the first available
133         // device of the appropriate type.
134         RefPtr<RealtimeMediaSource> videoSource = AVCaptureDeviceManager::singleton().bestSourcesForTypeAndConstraints(RealtimeMediaSource::Video, videoConstraints.get()).at(0);
135         ASSERT(videoSource);
136         
137         videoSources.append(videoSource.release());
138     }
139     
140     client->didCreateStream(MediaStreamPrivate::create(audioSources, videoSources));
141 }
142
143 void RealtimeMediaSourceCenterMac::createMediaStream(MediaStreamCreationClient* client, const String& audioDeviceID, const String& videoDeviceID)
144 {
145     ASSERT(client);
146     Vector<RefPtr<RealtimeMediaSource>> audioSources;
147     Vector<RefPtr<RealtimeMediaSource>> videoSources;
148
149     if (!audioDeviceID.isEmpty()) {
150         RefPtr<RealtimeMediaSource> audioSource = AVCaptureDeviceManager::singleton().sourceWithUID(audioDeviceID, RealtimeMediaSource::Audio, nullptr);
151         if (audioSource)
152             audioSources.append(audioSource.release());
153     }
154     if (!videoDeviceID.isEmpty()) {
155         RefPtr<RealtimeMediaSource> videoSource = AVCaptureDeviceManager::singleton().sourceWithUID(videoDeviceID, RealtimeMediaSource::Video, nullptr);
156         if (videoSource)
157             videoSources.append(videoSource.release());
158     }
159
160     client->didCreateStream(MediaStreamPrivate::create(audioSources, videoSources));
161 }
162
163 bool RealtimeMediaSourceCenterMac::getMediaStreamTrackSources(PassRefPtr<MediaStreamTrackSourcesRequestClient> prpClient)
164 {
165     RefPtr<MediaStreamTrackSourcesRequestClient> requestClient = prpClient;
166
167     TrackSourceInfoVector sources = AVCaptureDeviceManager::singleton().getSourcesInfo(requestClient->requestOrigin());
168
169     callOnMainThread([this, requestClient, sources] {
170         requestClient->didCompleteRequest(sources);
171     });
172
173     return true;
174 }
175
176 RefPtr<TrackSourceInfo> RealtimeMediaSourceCenterMac::sourceWithUID(const String& UID, RealtimeMediaSource::Type type, MediaConstraints* constraints)
177 {
178     RefPtr<RealtimeMediaSource> mediaSource = AVCaptureDeviceManager::singleton().sourceWithUID(UID, type, constraints);
179     if (!mediaSource)
180         return nullptr;
181     return TrackSourceInfo::create(mediaSource->persistentID(), mediaSource->id(), mediaSource->type() == RealtimeMediaSource::Type::Video ? TrackSourceInfo::SourceKind::Video : TrackSourceInfo::SourceKind::Audio, mediaSource->name());
182 }
183
184 } // namespace WebCore
185
186 #endif // ENABLE(MEDIA_STREAM)