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=\"supports-multiple-secure-codecs\" value=\"false\" />\n"
35"        <Setting name=\"supports-secure-with-non-secure-codec\" value=\"true\" />\n"
36"    </Settings>\n"
37"    <Encoders>\n"
38"        <MediaCodec name=\"OMX.qcom.video.encoder.avc\" type=\"video/avc\" update=\"true\" >\n"
39"            <Limit name=\"max-supported-instances\" value=\"4\" />\n"
40"        </MediaCodec>\n"
41"        <MediaCodec name=\"OMX.qcom.video.encoder.mpeg4\" type=\"video/mp4v-es\" update=\"true\" >\n"
42"            <Limit name=\"max-supported-instances\" value=\"4\" />\n"
43"        </MediaCodec>\n"
44"    </Encoders>\n"
45"    <Decoders>\n"
46"        <MediaCodec name=\"OMX.qcom.video.decoder.avc.secure\" type=\"video/avc\" update=\"true\" >\n"
47"            <Limit name=\"max-supported-instances\" value=\"1\" />\n"
48"        </MediaCodec>\n"
49"        <MediaCodec name=\"OMX.qcom.video.decoder.h263\" type=\"video/3gpp\" update=\"true\" >\n"
50"            <Limit name=\"max-supported-instances\" value=\"4\" />\n"
51"        </MediaCodec>\n"
52"        <MediaCodec name=\"OMX.qcom.video.decoder.mpeg2\" type=\"video/mpeg2\" update=\"true\" >\n"
53"            <Limit name=\"max-supported-instances\" value=\"3\" />\n"
54"        </MediaCodec>\n"
55"        <MediaCodec name=\"OMX.qcom.video.decoder.mpeg4\" type=\"video/mp4v-es\" update=\"true\" >\n"
56"            <Limit name=\"max-supported-instances\" value=\"3\" />\n"
57"        </MediaCodec>\n"
58"    </Decoders>\n"
59"</MediaCodecs>\n";
60
61class MediaCodecListOverridesTest : public ::testing::Test {
62public:
63    MediaCodecListOverridesTest() {}
64
65    void addMaxInstancesSetting(
66            const AString &key,
67            const AString &value,
68            KeyedVector<AString, CodecSettings> *results) {
69        CodecSettings settings;
70        settings.add("max-supported-instances", value);
71        results->add(key, settings);
72    }
73
74    void verifyProfileResults(const KeyedVector<AString, CodecSettings> &results) {
75        EXPECT_LT(0u, results.size());
76        for (size_t i = 0; i < results.size(); ++i) {
77            AString key = results.keyAt(i);
78            CodecSettings settings = results.valueAt(i);
79            EXPECT_EQ(1u, settings.size());
80            EXPECT_TRUE(settings.keyAt(0) == "max-supported-instances");
81            AString valueS = settings.valueAt(0);
82            int32_t value = strtol(valueS.c_str(), NULL, 10);
83            EXPECT_LT(0, value);
84            ALOGV("profileCodecs results %s %s", key.c_str(), valueS.c_str());
85        }
86    }
87
88    void exportTestResultsToXML(const char *fileName) {
89        CodecSettings gR;
90        gR.add("supports-multiple-secure-codecs", "false");
91        gR.add("supports-secure-with-non-secure-codec", "true");
92        KeyedVector<AString, CodecSettings> eR;
93        addMaxInstancesSetting("OMX.qcom.video.encoder.avc video/avc", "4", &eR);
94        addMaxInstancesSetting("OMX.qcom.video.encoder.mpeg4 video/mp4v-es", "4", &eR);
95        KeyedVector<AString, CodecSettings> dR;
96        addMaxInstancesSetting("OMX.qcom.video.decoder.avc.secure video/avc", "1", &dR);
97        addMaxInstancesSetting("OMX.qcom.video.decoder.h263 video/3gpp", "4", &dR);
98        addMaxInstancesSetting("OMX.qcom.video.decoder.mpeg2 video/mpeg2", "3", &dR);
99        addMaxInstancesSetting("OMX.qcom.video.decoder.mpeg4 video/mp4v-es", "3", &dR);
100
101        exportResultsToXML(fileName, gR, eR, dR);
102    }
103};
104
105TEST_F(MediaCodecListOverridesTest, splitString) {
106    AString s = "abc123";
107    AString delimiter = " ";
108    AString s1;
109    AString s2;
110    EXPECT_FALSE(splitString(s, delimiter, &s1, &s2));
111    s = "abc 123";
112    EXPECT_TRUE(splitString(s, delimiter, &s1, &s2));
113    EXPECT_TRUE(s1 == "abc");
114    EXPECT_TRUE(s2 == "123");
115}
116
117// TODO: the codec component never returns OMX_EventCmdComplete in unit test.
118TEST_F(MediaCodecListOverridesTest, DISABLED_profileCodecs) {
119    sp<IMediaCodecList> list = MediaCodecList::getInstance();
120    Vector<sp<MediaCodecInfo>> infos;
121    for (size_t i = 0; i < list->countCodecs(); ++i) {
122        infos.push_back(list->getCodecInfo(i));
123    }
124    CodecSettings global_results;
125    KeyedVector<AString, CodecSettings> encoder_results;
126    KeyedVector<AString, CodecSettings> decoder_results;
127    profileCodecs(
128            infos, &global_results, &encoder_results, &decoder_results, true /* forceToMeasure */);
129    verifyProfileResults(encoder_results);
130    verifyProfileResults(decoder_results);
131}
132
133TEST_F(MediaCodecListOverridesTest, exportTestResultsToXML) {
134    const char *fileName = "/sdcard/mediacodec_list_overrides_test.xml";
135    remove(fileName);
136
137    exportTestResultsToXML(fileName);
138
139    // verify
140    AString overrides;
141    FILE *f = fopen(fileName, "rb");
142    ASSERT_TRUE(f != NULL);
143    fseek(f, 0, SEEK_END);
144    long size = ftell(f);
145    rewind(f);
146
147    char *buf = (char *)malloc(size);
148    EXPECT_EQ((size_t)1, fread(buf, size, 1, f));
149    overrides.setTo(buf, size);
150    fclose(f);
151    free(buf);
152
153    AString expected;
154    expected.append(getProfilingVersionString());
155    expected.append("\n");
156    expected.append(kTestOverridesStr);
157    EXPECT_TRUE(overrides == expected);
158
159    remove(fileName);
160}
161
162} // namespace android
163