19e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu/*
29e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * Copyright 2015 The Android Open Source Project
39e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu *
49e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * Licensed under the Apache License, Version 2.0 (the "License");
59e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * you may not use this file except in compliance with the License.
69e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * You may obtain a copy of the License at
79e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu *
89e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu *      http://www.apache.org/licenses/LICENSE-2.0
99e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu *
109e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * Unless required by applicable law or agreed to in writing, software
119e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * distributed under the License is distributed on an "AS IS" BASIS,
129e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * See the License for the specific language governing permissions and
149e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu * limitations under the License.
159e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu */
169e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
179e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu// #define LOG_NDEBUG 0
189e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu#define LOG_TAG "MediaCodecListOverrides_test"
199e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu#include <utils/Log.h>
209e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
219e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu#include <gtest/gtest.h>
229e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
239e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu#include "MediaCodecListOverrides.h"
249e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
259e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu#include <media/MediaCodecInfo.h>
269e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu#include <media/stagefright/foundation/AMessage.h>
279e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu#include <media/stagefright/MediaCodecList.h>
289e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
299e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wunamespace android {
309e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
319e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wustatic const char kTestOverridesStr[] =
329e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"<MediaCodecs>\n"
339e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"    <Settings>\n"
3465c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu"        <Setting name=\"supports-multiple-secure-codecs\" value=\"false\" />\n"
3565c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu"        <Setting name=\"supports-secure-with-non-secure-codec\" value=\"true\" />\n"
369e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"    </Settings>\n"
379e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"    <Encoders>\n"
389e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"        <MediaCodec name=\"OMX.qcom.video.encoder.avc\" type=\"video/avc\" update=\"true\" >\n"
399e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"            <Limit name=\"max-supported-instances\" value=\"4\" />\n"
409e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"        </MediaCodec>\n"
419e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"        <MediaCodec name=\"OMX.qcom.video.encoder.mpeg4\" type=\"video/mp4v-es\" update=\"true\" >\n"
429e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"            <Limit name=\"max-supported-instances\" value=\"4\" />\n"
439e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"        </MediaCodec>\n"
449e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"    </Encoders>\n"
459e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"    <Decoders>\n"
469e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"        <MediaCodec name=\"OMX.qcom.video.decoder.avc.secure\" type=\"video/avc\" update=\"true\" >\n"
479e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"            <Limit name=\"max-supported-instances\" value=\"1\" />\n"
489e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"        </MediaCodec>\n"
4965c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu"        <MediaCodec name=\"OMX.qcom.video.decoder.h263\" type=\"video/3gpp\" update=\"true\" >\n"
5065c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu"            <Limit name=\"max-supported-instances\" value=\"4\" />\n"
519e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"        </MediaCodec>\n"
529e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"        <MediaCodec name=\"OMX.qcom.video.decoder.mpeg2\" type=\"video/mpeg2\" update=\"true\" >\n"
539e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"            <Limit name=\"max-supported-instances\" value=\"3\" />\n"
549e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"        </MediaCodec>\n"
559e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"        <MediaCodec name=\"OMX.qcom.video.decoder.mpeg4\" type=\"video/mp4v-es\" update=\"true\" >\n"
569e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"            <Limit name=\"max-supported-instances\" value=\"3\" />\n"
579e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"        </MediaCodec>\n"
589e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"    </Decoders>\n"
599e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu"</MediaCodecs>\n";
609e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
619e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wuclass MediaCodecListOverridesTest : public ::testing::Test {
629e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wupublic:
639e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    MediaCodecListOverridesTest() {}
649e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
659e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    void addMaxInstancesSetting(
669e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu            const AString &key,
679e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu            const AString &value,
689e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu            KeyedVector<AString, CodecSettings> *results) {
699e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        CodecSettings settings;
709e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        settings.add("max-supported-instances", value);
719e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        results->add(key, settings);
729e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    }
739e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
7465c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu    void verifyProfileResults(const KeyedVector<AString, CodecSettings> &results) {
7565c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu        EXPECT_LT(0u, results.size());
7665c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu        for (size_t i = 0; i < results.size(); ++i) {
7740d8899f60c5212af9d727ba0ffaaecf676ebd1dChih-Hung Hsieh            const AString &key = results.keyAt(i);
7840d8899f60c5212af9d727ba0ffaaecf676ebd1dChih-Hung Hsieh            const CodecSettings &settings = results.valueAt(i);
7965c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu            EXPECT_EQ(1u, settings.size());
8065c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu            EXPECT_TRUE(settings.keyAt(0) == "max-supported-instances");
8140d8899f60c5212af9d727ba0ffaaecf676ebd1dChih-Hung Hsieh            const AString &valueS = settings.valueAt(0);
8265c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu            int32_t value = strtol(valueS.c_str(), NULL, 10);
8365c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu            EXPECT_LT(0, value);
8465c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu            ALOGV("profileCodecs results %s %s", key.c_str(), valueS.c_str());
8565c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu        }
8665c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu    }
879e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
8865c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu    void exportTestResultsToXML(const char *fileName) {
8965c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu        CodecSettings gR;
9065c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu        gR.add("supports-multiple-secure-codecs", "false");
9165c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu        gR.add("supports-secure-with-non-secure-codec", "true");
9265c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu        KeyedVector<AString, CodecSettings> eR;
9365c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu        addMaxInstancesSetting("OMX.qcom.video.encoder.avc video/avc", "4", &eR);
9465c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu        addMaxInstancesSetting("OMX.qcom.video.encoder.mpeg4 video/mp4v-es", "4", &eR);
9565c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu        KeyedVector<AString, CodecSettings> dR;
9665c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu        addMaxInstancesSetting("OMX.qcom.video.decoder.avc.secure video/avc", "1", &dR);
9765c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu        addMaxInstancesSetting("OMX.qcom.video.decoder.h263 video/3gpp", "4", &dR);
9865c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu        addMaxInstancesSetting("OMX.qcom.video.decoder.mpeg2 video/mpeg2", "3", &dR);
9965c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu        addMaxInstancesSetting("OMX.qcom.video.decoder.mpeg4 video/mp4v-es", "3", &dR);
10065c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu
10165c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu        exportResultsToXML(fileName, gR, eR, dR);
1029e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    }
1039e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu};
1049e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
1059e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua WuTEST_F(MediaCodecListOverridesTest, splitString) {
1069e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    AString s = "abc123";
1079e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    AString delimiter = " ";
1089e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    AString s1;
1099e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    AString s2;
1109e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    EXPECT_FALSE(splitString(s, delimiter, &s1, &s2));
1119e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    s = "abc 123";
1129e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    EXPECT_TRUE(splitString(s, delimiter, &s1, &s2));
1139e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    EXPECT_TRUE(s1 == "abc");
1149e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    EXPECT_TRUE(s2 == "123");
1159e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu}
1169e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
1179e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu// TODO: the codec component never returns OMX_EventCmdComplete in unit test.
1189e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua WuTEST_F(MediaCodecListOverridesTest, DISABLED_profileCodecs) {
1199e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    sp<IMediaCodecList> list = MediaCodecList::getInstance();
1209e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    Vector<sp<MediaCodecInfo>> infos;
1219e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    for (size_t i = 0; i < list->countCodecs(); ++i) {
1229e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu        infos.push_back(list->getCodecInfo(i));
1239e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    }
1249ba21b9418d10ddcc39f08901e24fbf43d82b2bcRonghua Wu    CodecSettings global_results;
12565c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu    KeyedVector<AString, CodecSettings> encoder_results;
12665c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu    KeyedVector<AString, CodecSettings> decoder_results;
1279ba21b9418d10ddcc39f08901e24fbf43d82b2bcRonghua Wu    profileCodecs(
1289ba21b9418d10ddcc39f08901e24fbf43d82b2bcRonghua Wu            infos, &global_results, &encoder_results, &decoder_results, true /* forceToMeasure */);
12965c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu    verifyProfileResults(encoder_results);
13065c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua Wu    verifyProfileResults(decoder_results);
1319e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu}
1329e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
13365c8fbcf91f0f0b5f60a45d2777c36d396c4ba16Ronghua WuTEST_F(MediaCodecListOverridesTest, exportTestResultsToXML) {
1349e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    const char *fileName = "/sdcard/mediacodec_list_overrides_test.xml";
1359e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    remove(fileName);
1369e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
1379e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    exportTestResultsToXML(fileName);
1389e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
1399e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    // verify
1409e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    AString overrides;
1419e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    FILE *f = fopen(fileName, "rb");
1429e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    ASSERT_TRUE(f != NULL);
1439e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    fseek(f, 0, SEEK_END);
1449e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    long size = ftell(f);
1459e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    rewind(f);
1469e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
1479e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    char *buf = (char *)malloc(size);
148ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    EXPECT_EQ((size_t)1, fread(buf, size, 1, f));
1499e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    overrides.setTo(buf, size);
1509e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    fclose(f);
1519e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    free(buf);
1529e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
15319352b3287480394aa9963276305d5168a7adf85Ronghua Wu    AString expected;
15419352b3287480394aa9963276305d5168a7adf85Ronghua Wu    expected.append(getProfilingVersionString());
15519352b3287480394aa9963276305d5168a7adf85Ronghua Wu    expected.append("\n");
15619352b3287480394aa9963276305d5168a7adf85Ronghua Wu    expected.append(kTestOverridesStr);
15719352b3287480394aa9963276305d5168a7adf85Ronghua Wu    EXPECT_TRUE(overrides == expected);
1589e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
1599e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu    remove(fileName);
1609e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu}
1619e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu
1629e6955a19bf77ebf27b770e910efbe1ebf1ceac0Ronghua Wu} // namespace android
163