MediaCodecListOverrides_test.cpp revision ee4e1b1a63758941460ae79a064249d3a5189443
1/*
2 * Copyright 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// #define LOG_NDEBUG 0
18#define LOG_TAG "MediaCodecListOverrides_test"
19#include <utils/Log.h>
20
21#include <gtest/gtest.h>
22
23#include "MediaCodecListOverrides.h"
24
25#include <media/MediaCodecInfo.h>
26#include <media/stagefright/foundation/AMessage.h>
27#include <media/stagefright/MediaCodecList.h>
28
29namespace android {
30
31static const char kTestOverridesStr[] =
32"<MediaCodecs>\n"
33"    <Settings>\n"
34"        <Setting name=\"max-max-supported-instances\" value=\"8\" update=\"true\" />\n"
35"    </Settings>\n"
36"    <Encoders>\n"
37"        <MediaCodec name=\"OMX.qcom.video.encoder.mpeg4\" type=\"video/mp4v-es\" update=\"true\" >\n"
38"            <Quirk name=\"requires-allocate-on-input-ports\" />\n"
39"            <Limit name=\"bitrate\" range=\"1-20000000\" />\n"
40"            <Feature name=\"can-swap-width-height\" />\n"
41"        </MediaCodec>\n"
42"    </Encoders>\n"
43"    <Decoders>\n"
44"        <MediaCodec name=\"OMX.qcom.video.decoder.avc\" type=\"video/avc\" update=\"true\" >\n"
45"            <Quirk name=\"requires-allocate-on-input-ports\" />\n"
46"            <Limit name=\"size\" min=\"64x64\" max=\"1920x1088\" />\n"
47"        </MediaCodec>\n"
48"        <MediaCodec name=\"OMX.qcom.video.decoder.mpeg2\" type=\"different_mime\" update=\"true\" >\n"
49"        </MediaCodec>\n"
50"    </Decoders>\n"
51"</MediaCodecs>\n";
52
53static const char kTestOverridesStrNew1[] =
54"<MediaCodecs>\n"
55"    <Settings>\n"
56"        <Setting name=\"max-max-supported-instances\" value=\"8\" update=\"true\" />\n"
57"    </Settings>\n"
58"    <Encoders>\n"
59"        <MediaCodec name=\"OMX.qcom.video.encoder.avc\" type=\"video/avc\" update=\"true\" >\n"
60"            <Limit name=\"max-supported-instances\" value=\"4\" />\n"
61"        </MediaCodec>\n"
62"        <MediaCodec name=\"OMX.qcom.video.encoder.mpeg4\" type=\"video/mp4v-es\" update=\"true\" >\n"
63"            <Limit name=\"max-supported-instances\" value=\"4\" />\n"
64"            <Quirk name=\"requires-allocate-on-input-ports\" />\n"
65"            <Limit name=\"bitrate\" range=\"1-20000000\" />\n"
66"            <Feature name=\"can-swap-width-height\" />\n"
67"        </MediaCodec>\n"
68"    </Encoders>\n"
69"    <Decoders>\n"
70"        <MediaCodec name=\"OMX.qcom.video.decoder.mpeg4\" type=\"video/mp4v-es\" update=\"true\" >\n"
71"            <Limit name=\"max-supported-instances\" value=\"3\" />\n"
72"        </MediaCodec>\n"
73"        <MediaCodec name=\"OMX.qcom.video.decoder.h263\" type=\"video/3gpp\" update=\"true\" >\n"
74"            <Limit name=\"max-supported-instances\" value=\"4\" />\n"
75"        </MediaCodec>\n"
76"        <MediaCodec name=\"OMX.qcom.video.decoder.avc.secure\" type=\"video/avc\" update=\"true\" >\n"
77"            <Limit name=\"max-supported-instances\" value=\"1\" />\n"
78"        </MediaCodec>\n"
79"        <MediaCodec name=\"OMX.qcom.video.decoder.avc\" type=\"video/avc\" update=\"true\" >\n"
80"            <Quirk name=\"requires-allocate-on-input-ports\" />\n"
81"            <Limit name=\"size\" min=\"64x64\" max=\"1920x1088\" />\n"
82"        </MediaCodec>\n"
83"        <MediaCodec name=\"OMX.qcom.video.decoder.mpeg2\" type=\"different_mime\" update=\"true\" >\n"
84"        </MediaCodec>\n"
85"        <MediaCodec name=\"OMX.qcom.video.decoder.mpeg2\" type=\"video/mpeg2\" update=\"true\" >\n"
86"            <Limit name=\"max-supported-instances\" value=\"3\" />\n"
87"        </MediaCodec>\n"
88"    </Decoders>\n"
89"</MediaCodecs>\n";
90
91static const char kTestOverridesStrNew2[] =
92"\n"
93"<MediaCodecs>\n"
94"    <Encoders>\n"
95"        <MediaCodec name=\"OMX.qcom.video.encoder.mpeg4\" type=\"video/mp4v-es\" update=\"true\" >\n"
96"            <Limit name=\"max-supported-instances\" value=\"4\" />\n"
97"        </MediaCodec>\n"
98"        <MediaCodec name=\"OMX.qcom.video.encoder.avc\" type=\"video/avc\" update=\"true\" >\n"
99"            <Limit name=\"max-supported-instances\" value=\"4\" />\n"
100"        </MediaCodec>\n"
101"    </Encoders>\n"
102"    <Decoders>\n"
103"        <MediaCodec name=\"OMX.qcom.video.decoder.mpeg4\" type=\"video/mp4v-es\" update=\"true\" >\n"
104"            <Limit name=\"max-supported-instances\" value=\"3\" />\n"
105"        </MediaCodec>\n"
106"        <MediaCodec name=\"OMX.qcom.video.decoder.mpeg2\" type=\"video/mpeg2\" update=\"true\" >\n"
107"            <Limit name=\"max-supported-instances\" value=\"3\" />\n"
108"        </MediaCodec>\n"
109"        <MediaCodec name=\"OMX.qcom.video.decoder.h263\" type=\"video/3gpp\" update=\"true\" >\n"
110"            <Limit name=\"max-supported-instances\" value=\"4\" />\n"
111"        </MediaCodec>\n"
112"        <MediaCodec name=\"OMX.qcom.video.decoder.avc.secure\" type=\"video/avc\" update=\"true\" >\n"
113"            <Limit name=\"max-supported-instances\" value=\"1\" />\n"
114"        </MediaCodec>\n"
115"    </Decoders>\n"
116"</MediaCodecs>\n";
117
118class MediaCodecListOverridesTest : public ::testing::Test {
119public:
120    MediaCodecListOverridesTest() {}
121
122    void verifyOverrides(const KeyedVector<AString, CodecSettings> &overrides) {
123        EXPECT_EQ(3u, overrides.size());
124
125        EXPECT_TRUE(overrides.keyAt(0) == "OMX.qcom.video.decoder.avc video/avc decoder");
126        const CodecSettings &settings0 = overrides.valueAt(0);
127        EXPECT_EQ(1u, settings0.size());
128        EXPECT_TRUE(settings0.keyAt(0) == "max-supported-instances");
129        EXPECT_TRUE(settings0.valueAt(0) == "4");
130
131        EXPECT_TRUE(overrides.keyAt(1) == "OMX.qcom.video.encoder.avc video/avc encoder");
132        const CodecSettings &settings1 = overrides.valueAt(1);
133        EXPECT_EQ(1u, settings1.size());
134        EXPECT_TRUE(settings1.keyAt(0) == "max-supported-instances");
135        EXPECT_TRUE(settings1.valueAt(0) == "3");
136
137        EXPECT_TRUE(overrides.keyAt(2) == "global");
138        const CodecSettings &settings2 = overrides.valueAt(2);
139        EXPECT_EQ(3u, settings2.size());
140        EXPECT_TRUE(settings2.keyAt(0) == "max-max-supported-instances");
141        EXPECT_TRUE(settings2.valueAt(0) == "8");
142        EXPECT_TRUE(settings2.keyAt(1) == "supports-multiple-secure-codecs");
143        EXPECT_TRUE(settings2.valueAt(1) == "false");
144        EXPECT_TRUE(settings2.keyAt(2) == "supports-secure-with-non-secure-codec");
145        EXPECT_TRUE(settings2.valueAt(2) == "true");
146    }
147
148    void verifySetting(const sp<AMessage> &details, const char *name, const char *value) {
149        AString value1;
150        EXPECT_TRUE(details->findString(name, &value1));
151        EXPECT_TRUE(value1 == value);
152    }
153
154    void createTestInfos(Vector<sp<MediaCodecInfo>> *infos) {
155        const char *name = "OMX.qcom.video.decoder.avc";
156        const bool encoder = false;
157        const char *mime = "video/avc";
158        sp<MediaCodecInfo> info = new MediaCodecInfo(name, encoder, mime);
159        infos->push_back(info);
160        const sp<MediaCodecInfo::Capabilities> caps = info->getCapabilitiesFor(mime);
161        const sp<AMessage> details = caps->getDetails();
162        details->setString("cap1", "value1");
163        details->setString("max-max-supported-instances", "16");
164
165        info = new MediaCodecInfo("anothercodec", true, "anothermime");
166        infos->push_back(info);
167    }
168
169    void addMaxInstancesSetting(
170            const AString &key,
171            const AString &value,
172            KeyedVector<AString, CodecSettings> *results) {
173        CodecSettings settings;
174        settings.add("max-supported-instances", value);
175        results->add(key, settings);
176    }
177
178    void exportTestResultsToXML(const char *fileName) {
179        KeyedVector<AString, CodecSettings> r;
180        addMaxInstancesSetting("OMX.qcom.video.decoder.avc.secure video/avc decoder", "1", &r);
181        addMaxInstancesSetting("OMX.qcom.video.decoder.h263 video/3gpp decoder", "4", &r);
182        addMaxInstancesSetting("OMX.qcom.video.decoder.mpeg2 video/mpeg2 decoder", "3", &r);
183        addMaxInstancesSetting("OMX.qcom.video.decoder.mpeg4 video/mp4v-es decoder", "3", &r);
184        addMaxInstancesSetting("OMX.qcom.video.encoder.avc video/avc encoder", "4", &r);
185        addMaxInstancesSetting("OMX.qcom.video.encoder.mpeg4 video/mp4v-es encoder", "4", &r);
186
187        exportResultsToXML(fileName, r);
188    }
189};
190
191TEST_F(MediaCodecListOverridesTest, splitString) {
192    AString s = "abc123";
193    AString delimiter = " ";
194    AString s1;
195    AString s2;
196    EXPECT_FALSE(splitString(s, delimiter, &s1, &s2));
197    s = "abc 123";
198    EXPECT_TRUE(splitString(s, delimiter, &s1, &s2));
199    EXPECT_TRUE(s1 == "abc");
200    EXPECT_TRUE(s2 == "123");
201
202    s = "abc123xyz";
203    delimiter = ",";
204    AString s3;
205    EXPECT_FALSE(splitString(s, delimiter, &s1, &s2, &s3));
206    s = "abc,123xyz";
207    EXPECT_FALSE(splitString(s, delimiter, &s1, &s2, &s3));
208    s = "abc,123,xyz";
209    EXPECT_TRUE(splitString(s, delimiter, &s1, &s2, &s3));
210    EXPECT_TRUE(s1 == "abc");
211    EXPECT_TRUE(s2 == "123" );
212    EXPECT_TRUE(s3 == "xyz");
213}
214
215// TODO: the codec component never returns OMX_EventCmdComplete in unit test.
216TEST_F(MediaCodecListOverridesTest, DISABLED_profileCodecs) {
217    sp<IMediaCodecList> list = MediaCodecList::getInstance();
218    Vector<sp<MediaCodecInfo>> infos;
219    for (size_t i = 0; i < list->countCodecs(); ++i) {
220        infos.push_back(list->getCodecInfo(i));
221    }
222    KeyedVector<AString, CodecSettings> results;
223    profileCodecs(infos, &results, true /* forceToMeasure */);
224    EXPECT_LT(0u, results.size());
225    for (size_t i = 0; i < results.size(); ++i) {
226        AString key = results.keyAt(i);
227        CodecSettings settings = results.valueAt(i);
228        EXPECT_EQ(1u, settings.size());
229        EXPECT_TRUE(settings.keyAt(0) == "max-supported-instances");
230        AString valueS = settings.valueAt(0);
231        int32_t value = strtol(valueS.c_str(), NULL, 10);
232        EXPECT_LT(0, value);
233        ALOGV("profileCodecs results %s %s", key.c_str(), valueS.c_str());
234    }
235}
236
237TEST_F(MediaCodecListOverridesTest, applyCodecSettings) {
238    AString codecInfo = "OMX.qcom.video.decoder.avc video/avc decoder";
239    Vector<sp<MediaCodecInfo>> infos;
240    createTestInfos(&infos);
241    CodecSettings settings;
242    settings.add("max-supported-instances", "3");
243    settings.add("max-max-supported-instances", "8");
244    applyCodecSettings(codecInfo, settings, &infos);
245
246    EXPECT_EQ(2u, infos.size());
247    EXPECT_TRUE(AString(infos[0]->getCodecName()) == "OMX.qcom.video.decoder.avc");
248    const sp<AMessage> details = infos[0]->getCapabilitiesFor("video/avc")->getDetails();
249    verifySetting(details, "max-supported-instances", "3");
250    verifySetting(details, "max-max-supported-instances", "8");
251
252    EXPECT_TRUE(AString(infos[1]->getCodecName()) == "anothercodec");
253    EXPECT_EQ(0u, infos[1]->getCapabilitiesFor("anothermime")->getDetails()->countEntries());
254}
255
256TEST_F(MediaCodecListOverridesTest, exportResultsToExistingFile) {
257    const char *fileName = "/sdcard/mediacodec_list_overrides_test.xml";
258    remove(fileName);
259
260    FILE *f = fopen(fileName, "wb");
261    if (f == NULL) {
262        ALOGW("Failed to open %s for writing.", fileName);
263        return;
264    }
265    EXPECT_EQ(
266            strlen(kTestOverridesStr),
267            fwrite(kTestOverridesStr, 1, strlen(kTestOverridesStr), f));
268    fclose(f);
269
270    exportTestResultsToXML(fileName);
271
272    // verify
273    AString overrides;
274    f = fopen(fileName, "rb");
275    ASSERT_TRUE(f != NULL);
276    fseek(f, 0, SEEK_END);
277    long size = ftell(f);
278    rewind(f);
279
280    char *buf = (char *)malloc(size);
281    EXPECT_EQ((size_t)1, fread(buf, size, 1, f));
282    overrides.setTo(buf, size);
283    fclose(f);
284    free(buf);
285
286    EXPECT_TRUE(overrides == kTestOverridesStrNew1);
287
288    remove(fileName);
289}
290
291TEST_F(MediaCodecListOverridesTest, exportResultsToEmptyFile) {
292    const char *fileName = "/sdcard/mediacodec_list_overrides_test.xml";
293    remove(fileName);
294
295    exportTestResultsToXML(fileName);
296
297    // verify
298    AString overrides;
299    FILE *f = fopen(fileName, "rb");
300    ASSERT_TRUE(f != NULL);
301    fseek(f, 0, SEEK_END);
302    long size = ftell(f);
303    rewind(f);
304
305    char *buf = (char *)malloc(size);
306    EXPECT_EQ((size_t)1, fread(buf, size, 1, f));
307    overrides.setTo(buf, size);
308    fclose(f);
309    free(buf);
310
311    EXPECT_TRUE(overrides == kTestOverridesStrNew2);
312
313    remove(fileName);
314}
315
316} // namespace android
317