1 | /* |
2 | * Copyright (C) 2018 Igalia S.L. |
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 |
11 | * copyright notice, this list of conditions and the following |
12 | * disclaimer in the documentation and/or other materials provided |
13 | * with the distribution. |
14 | * |
15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
18 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
19 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
20 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
21 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
25 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ |
27 | |
28 | #include "config.h" |
29 | #include "MediaEngineConfigurationFactory.h" |
30 | |
31 | #include "MediaCapabilitiesDecodingInfo.h" |
32 | #include "MediaCapabilitiesEncodingInfo.h" |
33 | #include "MediaDecodingConfiguration.h" |
34 | #include "MediaEncodingConfiguration.h" |
35 | #include "MediaEngineConfigurationFactoryMock.h" |
36 | #include <wtf/NeverDestroyed.h> |
37 | #include <wtf/Vector.h> |
38 | |
39 | #if PLATFORM(COCOA) |
40 | #include "MediaEngineConfigurationFactoryCocoa.h" |
41 | #endif |
42 | |
43 | #if USE(GSTREAMER) |
44 | #include "MediaEngineConfigurationFactoryGStreamer.h" |
45 | #endif |
46 | |
47 | namespace WebCore { |
48 | |
49 | static bool& mockEnabled() |
50 | { |
51 | static bool enabled; |
52 | return enabled; |
53 | } |
54 | |
55 | struct MediaEngineFactory { |
56 | void(*createDecodingConfiguration)(MediaDecodingConfiguration&&, MediaEngineConfigurationFactory::DecodingConfigurationCallback&&); |
57 | void(*createEncodingConfiguration)(MediaEncodingConfiguration&&, MediaEngineConfigurationFactory::EncodingConfigurationCallback&&); |
58 | }; |
59 | |
60 | using FactoryVector = Vector<MediaEngineFactory>; |
61 | static const FactoryVector& factories() |
62 | { |
63 | static NeverDestroyed<FactoryVector> factories = makeNeverDestroyed(FactoryVector({ |
64 | #if PLATFORM(COCOA) |
65 | { &createMediaPlayerDecodingConfigurationCocoa, nullptr }, |
66 | #endif |
67 | #if USE(GSTREAMER) |
68 | { &createMediaPlayerDecodingConfigurationGStreamer, nullptr }, |
69 | #endif |
70 | })); |
71 | return factories; |
72 | } |
73 | |
74 | void MediaEngineConfigurationFactory::createDecodingConfiguration(MediaDecodingConfiguration&& config, MediaEngineConfigurationFactory::DecodingConfigurationCallback&& callback) |
75 | { |
76 | if (mockEnabled()) { |
77 | MediaEngineConfigurationFactoryMock::createDecodingConfiguration(WTFMove(config), WTFMove(callback)); |
78 | return; |
79 | } |
80 | |
81 | auto factoryCallback = [] (auto factoryCallback, auto nextFactory, auto&& config, auto&& callback) mutable { |
82 | if (nextFactory == factories().end()) { |
83 | callback({{ }, WTFMove(config)}); |
84 | return; |
85 | } |
86 | |
87 | auto& factory = *nextFactory; |
88 | if (!factory.createDecodingConfiguration) { |
89 | callback({{ }, WTFMove(config)}); |
90 | return; |
91 | } |
92 | |
93 | factory.createDecodingConfiguration(WTFMove(config), [factoryCallback, nextFactory, config, callback = WTFMove(callback)] (auto&& info) mutable { |
94 | if (info.supported) { |
95 | callback(WTFMove(info)); |
96 | return; |
97 | } |
98 | |
99 | factoryCallback(factoryCallback, ++nextFactory, WTFMove(info.supportedConfiguration), WTFMove(callback)); |
100 | }); |
101 | }; |
102 | factoryCallback(factoryCallback, factories().begin(), config, WTFMove(callback)); |
103 | } |
104 | |
105 | void MediaEngineConfigurationFactory::createEncodingConfiguration(MediaEncodingConfiguration&& config, MediaEngineConfigurationFactory::EncodingConfigurationCallback&& callback) |
106 | { |
107 | if (mockEnabled()) { |
108 | MediaEngineConfigurationFactoryMock::createEncodingConfiguration(WTFMove(config), WTFMove(callback)); |
109 | return; |
110 | } |
111 | |
112 | auto factoryCallback = [] (auto factoryCallback, auto nextFactory, auto&& config, auto&& callback) mutable { |
113 | if (nextFactory == factories().end()) { |
114 | callback({ }); |
115 | return; |
116 | } |
117 | |
118 | auto& factory = *nextFactory; |
119 | if (!factory.createEncodingConfiguration) { |
120 | callback({ }); |
121 | return; |
122 | } |
123 | |
124 | factory.createEncodingConfiguration(WTFMove(config), [factoryCallback, nextFactory, callback = WTFMove(callback)] (auto&& info) mutable { |
125 | if (info.supported) { |
126 | callback(WTFMove(info)); |
127 | return; |
128 | } |
129 | |
130 | factoryCallback(factoryCallback, ++nextFactory, WTFMove(info.supportedConfiguration), WTFMove(callback)); |
131 | }); |
132 | }; |
133 | factoryCallback(factoryCallback, factories().begin(), WTFMove(config), WTFMove(callback)); |
134 | } |
135 | |
136 | void MediaEngineConfigurationFactory::enableMock() |
137 | { |
138 | mockEnabled() = true; |
139 | } |
140 | |
141 | void MediaEngineConfigurationFactory::disableMock() |
142 | { |
143 | mockEnabled() = false; |
144 | } |
145 | |
146 | } |
147 | |