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 "MediaEngineConfigurationFactoryMock.h"
30
31#include "ContentType.h"
32#include "MediaCapabilitiesDecodingInfo.h"
33#include "MediaCapabilitiesEncodingInfo.h"
34#include "MediaDecodingConfiguration.h"
35#include "MediaEncodingConfiguration.h"
36
37namespace WebCore {
38
39static bool canDecodeMedia(const MediaDecodingConfiguration& configuration)
40{
41 // The mock implementation supports only local file playback.
42 if (configuration.type == MediaDecodingType::MediaSource)
43 return false;
44
45 // Maxing out video decoding support at 720P.
46 auto videoConfig = configuration.video;
47 if (videoConfig && videoConfig->width > 1280 && videoConfig->height > 720)
48 return false;
49
50 // Only the "mock-with-alpha" codec supports alphaChannel
51 if (videoConfig && videoConfig->alphaChannel && videoConfig->alphaChannel.value()) {
52 if (ContentType(videoConfig->contentType).codecsParameter() != "mock-with-alpha")
53 return false;
54 }
55
56 // Audio decoding support limited to audio/mp4.
57 auto audioConfig = configuration.audio;
58 if (audioConfig)
59 return ContentType(audioConfig->contentType).containerType() == "audio/mp4";
60
61 return true;
62}
63
64static bool canSmoothlyDecodeMedia(const MediaDecodingConfiguration& configuration)
65{
66 auto videoConfig = configuration.video;
67 if (videoConfig && videoConfig->framerate > 30)
68 return false;
69
70 auto audioConfig = configuration.audio;
71 if (audioConfig)
72 return audioConfig->channels == "2";
73
74 return true;
75}
76
77static bool canPowerEfficientlyDecodeMedia(const MediaDecodingConfiguration& configuration)
78{
79 auto videoConfig = configuration.video;
80 if (videoConfig && ContentType(videoConfig->contentType).containerType() != "video/mp4")
81 return false;
82
83 auto audioConfig = configuration.audio;
84 if (audioConfig)
85 return audioConfig->bitrate <= 1000;
86
87 return true;
88}
89
90static bool canEncodeMedia(const MediaEncodingConfiguration& configuration)
91{
92 // The mock implementation supports only local file playback.
93 if (configuration.type == MediaEncodingType::Record)
94 return false;
95
96 // Maxing out video encoding support at 720P.
97 auto videoConfig = configuration.video;
98 if (videoConfig && videoConfig->width > 1280 && videoConfig->height > 720)
99 return false;
100
101 // Only the "mock-with-alpha" codec supports alphaChannel
102 if (videoConfig && videoConfig->alphaChannel && videoConfig->alphaChannel.value()) {
103 if (ContentType(videoConfig->contentType).codecsParameter() != "mock-with-alpha")
104 return false;
105 }
106
107 // Audio encoding support limited to audio/mp4.
108 auto audioConfig = configuration.audio;
109 if (audioConfig && ContentType(audioConfig->contentType).containerType() != "audio/mp4")
110 return false;
111
112 return true;
113}
114
115static bool canSmoothlyEncodeMedia(const MediaEncodingConfiguration& configuration)
116{
117 auto videoConfig = configuration.video;
118 if (videoConfig && videoConfig->framerate > 30)
119 return false;
120
121 auto audioConfig = configuration.audio;
122 if (audioConfig && audioConfig->channels != "2")
123 return false;
124
125 return true;
126}
127
128static bool canPowerEfficientlyEncodeMedia(const MediaEncodingConfiguration& configuration)
129{
130 auto videoConfig = configuration.video;
131 if (videoConfig && ContentType(videoConfig->contentType).containerType() != "video/mp4")
132 return false;
133
134 auto audioConfig = configuration.audio;
135 if (audioConfig && audioConfig->bitrate > 1000)
136 return false;
137
138 return true;
139}
140
141void MediaEngineConfigurationFactoryMock::createDecodingConfiguration(MediaDecodingConfiguration&& configuration, DecodingConfigurationCallback&& callback)
142{
143 if (!canDecodeMedia(configuration)) {
144 MediaCapabilitiesDecodingInfo info { WTFMove(configuration) };
145 callback(WTFMove(info));
146 return;
147 }
148 callback({{ true, canSmoothlyDecodeMedia(configuration), canPowerEfficientlyDecodeMedia(configuration) }, WTFMove(configuration)});
149}
150
151void MediaEngineConfigurationFactoryMock::createEncodingConfiguration(MediaEncodingConfiguration&& configuration, EncodingConfigurationCallback&& callback)
152{
153 if (!canEncodeMedia(configuration)) {
154 callback({{ }, WTFMove(configuration) });
155 return;
156 }
157 callback({{ true, canSmoothlyEncodeMedia(configuration), canPowerEfficientlyEncodeMedia(configuration) }, WTFMove(configuration)});
158}
159
160} // namespace WebCore
161