Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7c9913d5 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "MediaTesting: Add MetaDataUtils Unit Test" am: 1fc724e9 am: 77b4db61

Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/1318786

Change-Id: Ie02d29d7b8d0d3d70d851c06eae37ab6889271bf
parents ef4acc23 77b4db61
Loading
Loading
Loading
Loading
+50 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

cc_test {
    name: "MetaDataUtilsTest",
    gtest: true,

    srcs: [
        "MetaDataUtilsTest.cpp",
    ],

    static_libs: [
        "libstagefright_metadatautils",
        "libstagefright_esds",
    ],

    shared_libs: [
        "liblog",
        "libutils",
        "libmediandk",
        "libstagefright",
        "libstagefright_foundation",
    ],

    cflags: [
        "-Werror",
        "-Wall",
    ],

    sanitize: {
        cfi: true,
        misc_undefined: [
            "unsigned-integer-overflow",
            "signed-integer-overflow",
        ],
    },
}
+30 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2020 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->
<configuration description="Test module config for MetaDataUtils unit test">
    <option name="test-suite-tag" value="MetaDataUtilsTest" />
    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
        <option name="cleanup" value="false" />
        <option name="push" value="MetaDataUtilsTest->/data/local/tmp/MetaDataUtilsTest" />
        <option name="push-file"
            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/metadatautils/MetaDataUtilsTestRes-1.0.zip?unzip=true"
            value="/data/local/tmp/MetaDataUtilsTestRes/" />
    </target_preparer>
    <test class="com.android.tradefed.testtype.GTest" >
        <option name="native-test-device-path" value="/data/local/tmp" />
        <option name="module-name" value="MetaDataUtilsTest" />
        <option name="native-test-flag" value="-P /data/local/tmp/MetaDataUtilsTestRes/" />
    </test>
</configuration>
+490 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "MetaDataUtilsTest"
#include <utils/Log.h>

#include <fstream>
#include <string>

#include <ESDS.h>
#include <media/NdkMediaFormat.h>
#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaDataBase.h>
#include <media/stagefright/MetaDataUtils.h>
#include <media/stagefright/foundation/ABitReader.h>

#include "MetaDataUtilsTestEnvironment.h"

constexpr uint8_t kAdtsCsdSize = 7;
// from AAC specs: https://www.iso.org/standard/43345.html
constexpr int32_t kSamplingFreq[] = {96000, 88200, 64000, 48000, 44100, 32000,
                                     24000, 22050, 16000, 12000, 11025, 8000};
constexpr uint8_t kMaxSamplingFreqIndex = sizeof(kSamplingFreq) / sizeof(kSamplingFreq[0]);

static MetaDataUtilsTestEnvironment *gEnv = nullptr;

using namespace android;

class MetaDataValidate {
  public:
    MetaDataValidate() : mInputBuffer(nullptr) {}

    ~MetaDataValidate() {
        if (mInputBuffer) {
            delete[] mInputBuffer;
            mInputBuffer = nullptr;
        }
    }

    void SetUpMetaDataValidate(string fileName) {
        struct stat buf;
        int8_t err = stat(fileName.c_str(), &buf);
        ASSERT_EQ(err, 0) << "Failed to get file information for file: " << fileName;

        mInputBufferSize = buf.st_size;
        FILE *inputFilePtr = fopen(fileName.c_str(), "rb+");
        ASSERT_NE(inputFilePtr, nullptr) << "Failed to open file: " << fileName;

        mInputBuffer = new uint8_t[mInputBufferSize];
        ASSERT_NE(mInputBuffer, nullptr)
                << "Failed to allocate memory of size: " << mInputBufferSize;

        int32_t numBytes =
                fread((char *)mInputBuffer, sizeof(uint8_t), mInputBufferSize, inputFilePtr);
        ASSERT_EQ(numBytes, mInputBufferSize) << numBytes << " of " << mInputBufferSize << " read";

        fclose(inputFilePtr);
    }

    size_t mInputBufferSize;
    const uint8_t *mInputBuffer;
};

class AvcCSDTest : public ::testing::TestWithParam<
                           tuple<string /*inputFile*/, size_t /*avcWidth*/, size_t /*avcHeight*/>> {
  public:
    AvcCSDTest() : mInputBuffer(nullptr) {}

    ~AvcCSDTest() {
        if (mInputBuffer) {
            delete[] mInputBuffer;
            mInputBuffer = nullptr;
        }
    }
    virtual void SetUp() override {
        tuple<string, size_t, size_t> params = GetParam();
        string inputFile = gEnv->getRes() + get<0>(params);
        mFrameWidth = get<1>(params);
        mFrameHeight = get<2>(params);

        struct stat buf;
        int8_t err = stat(inputFile.c_str(), &buf);
        ASSERT_EQ(err, 0) << "Failed to get information for file: " << inputFile;

        mInputBufferSize = buf.st_size;
        FILE *inputFilePtr = fopen(inputFile.c_str(), "rb+");
        ASSERT_NE(inputFilePtr, nullptr) << "Failed to open file: " << inputFile;

        mInputBuffer = new uint8_t[mInputBufferSize];
        ASSERT_NE(mInputBuffer, nullptr)
                << "Failed to create a buffer of size: " << mInputBufferSize;

        int32_t numBytes =
                fread((char *)mInputBuffer, sizeof(uint8_t), mInputBufferSize, inputFilePtr);
        ASSERT_EQ(numBytes, mInputBufferSize) << numBytes << " of " << mInputBufferSize << " read";

        fclose(inputFilePtr);
    }

    size_t mFrameWidth;
    size_t mFrameHeight;
    size_t mInputBufferSize;
    const uint8_t *mInputBuffer;
};

class AvcCSDValidateTest : public MetaDataValidate,
                           public ::testing::TestWithParam<string /*inputFile*/> {
  public:
    virtual void SetUp() override {
        string inputFile = gEnv->getRes() + GetParam();

        ASSERT_NO_FATAL_FAILURE(SetUpMetaDataValidate(inputFile));
    }
};

class AacCSDTest
    : public ::testing::TestWithParam<tuple<uint32_t /*profile*/, uint32_t /*samplingFreqIndex*/,
                                            uint32_t /*channelConfig*/>> {
  public:
    virtual void SetUp() override {
        tuple<uint32_t, uint32_t, uint32_t> params = GetParam();
        mAacProfile = get<0>(params);
        mAacSamplingFreqIndex = get<1>(params);
        mAacChannelConfig = get<2>(params);
    }

    uint32_t mAacProfile;
    uint32_t mAacSamplingFreqIndex;
    uint32_t mAacChannelConfig;
};

class AacADTSTest
    : public ::testing::TestWithParam<
              tuple<string /*adtsFile*/, uint32_t /*channelCount*/, uint32_t /*sampleRate*/>> {
  public:
    AacADTSTest() : mInputBuffer(nullptr) {}

    virtual void SetUp() override {
        tuple<string, uint32_t, uint32_t> params = GetParam();
        string fileName = gEnv->getRes() + get<0>(params);
        mAacChannelCount = get<1>(params);
        mAacSampleRate = get<2>(params);

        FILE *filePtr = fopen(fileName.c_str(), "r");
        ASSERT_NE(filePtr, nullptr) << "Failed to open file: " << fileName;

        mInputBuffer = new uint8_t[kAdtsCsdSize];
        ASSERT_NE(mInputBuffer, nullptr) << "Failed to allocate a memory of size: " << kAdtsCsdSize;

        int32_t numBytes = fread((void *)mInputBuffer, sizeof(uint8_t), kAdtsCsdSize, filePtr);
        ASSERT_EQ(numBytes, kAdtsCsdSize)
                << "Failed to read complete file, bytes read: " << numBytes;

        fclose(filePtr);
    }
    int32_t mAacChannelCount;
    int32_t mAacSampleRate;
    const uint8_t *mInputBuffer;
};

class AacCSDValidateTest : public MetaDataValidate,
                           public ::testing::TestWithParam<string /*inputFile*/> {
  public:
    virtual void SetUp() override {
        string inputFile = gEnv->getRes() + GetParam();

        ASSERT_NO_FATAL_FAILURE(SetUpMetaDataValidate(inputFile));
    }
};

class VorbisTest : public ::testing::TestWithParam<pair<string /*fileName*/, string /*infoFile*/>> {
  public:
    virtual void SetUp() override {
        pair<string, string> params = GetParam();
        string inputMediaFile = gEnv->getRes() + params.first;
        mInputFileStream.open(inputMediaFile, ifstream::in);
        ASSERT_TRUE(mInputFileStream.is_open()) << "Failed to open data file: " << inputMediaFile;

        string inputInfoFile = gEnv->getRes() + params.second;
        mInfoFileStream.open(inputInfoFile, ifstream::in);
        ASSERT_TRUE(mInputFileStream.is_open()) << "Failed to open data file: " << inputInfoFile;
        ASSERT_FALSE(inputInfoFile.empty()) << "Empty info file: " << inputInfoFile;
    }

    ~VorbisTest() {
        if (mInputFileStream.is_open()) mInputFileStream.close();
        if (mInfoFileStream.is_open()) mInfoFileStream.close();
    }

    ifstream mInputFileStream;
    ifstream mInfoFileStream;
};

TEST_P(AvcCSDTest, AvcCSDValidationTest) {
    AMediaFormat *csdData = AMediaFormat_new();
    ASSERT_NE(csdData, nullptr) << "Failed to create AMedia format";

    bool status = MakeAVCCodecSpecificData(csdData, mInputBuffer, mInputBufferSize);
    ASSERT_TRUE(status) << "Failed to make AVC CSD from AMediaFormat";

    int32_t avcWidth = -1;
    status = AMediaFormat_getInt32(csdData, AMEDIAFORMAT_KEY_WIDTH, &avcWidth);
    ASSERT_TRUE(status) << "Failed to get avc width";
    ASSERT_EQ(avcWidth, mFrameWidth);

    int32_t avcHeight = -1;
    status = AMediaFormat_getInt32(csdData, AMEDIAFORMAT_KEY_HEIGHT, &avcHeight);
    ASSERT_TRUE(status) << "Failed to get avc height";
    ASSERT_EQ(avcHeight, mFrameHeight);

    const char *mimeType = "";
    status = AMediaFormat_getString(csdData, AMEDIAFORMAT_KEY_MIME, &mimeType);
    ASSERT_TRUE(status) << "Failed to get the mime type";
    ASSERT_STREQ(mimeType, MEDIA_MIMETYPE_VIDEO_AVC);

    MetaDataBase *metaData = new MetaDataBase();
    ASSERT_NE(metaData, nullptr) << "Failed to create MetaData Base";

    status = MakeAVCCodecSpecificData(*metaData, mInputBuffer, mInputBufferSize);
    ASSERT_TRUE(status) << "Failed to make AVC CSD from MetaDataBase";

    avcWidth = -1;
    status = metaData->findInt32(kKeyWidth, &avcWidth);
    ASSERT_TRUE(status) << "Failed to find the width";
    ASSERT_EQ(avcWidth, mFrameWidth);

    avcHeight = -1;
    status = metaData->findInt32(kKeyHeight, &avcHeight);
    ASSERT_TRUE(status) << "Failed to find the height";
    ASSERT_EQ(avcHeight, mFrameHeight);

    void *csdAMediaFormatBuffer = nullptr;
    size_t csdAMediaFormatSize;
    status = AMediaFormat_getBuffer(csdData, AMEDIAFORMAT_KEY_CSD_AVC, &csdAMediaFormatBuffer,
                                    &csdAMediaFormatSize);
    ASSERT_TRUE(status) << "Failed to get the CSD from AMediaFormat";
    ASSERT_NE(csdAMediaFormatBuffer, nullptr) << "Invalid CSD from AMediaFormat";

    const void *csdMetaDataBaseBuffer = nullptr;
    size_t csdMetaDataBaseSize = 0;
    uint32_t mediaType;
    status = metaData->findData(kKeyAVCC, &mediaType, &csdMetaDataBaseBuffer, &csdMetaDataBaseSize);
    ASSERT_TRUE(status) << "Failed to get the CSD from MetaDataBase";
    ASSERT_NE(csdMetaDataBaseBuffer, nullptr) << "Invalid CSD from MetaDataBase";
    ASSERT_GT(csdMetaDataBaseSize, 0) << "CSD size must be greater than 0";
    ASSERT_EQ(csdMetaDataBaseSize, csdAMediaFormatSize)
            << "CSD size of MetaData type and AMediaFormat type must be same";

    int32_t result = memcmp(csdAMediaFormatBuffer, csdMetaDataBaseBuffer, csdAMediaFormatSize);
    ASSERT_EQ(result, 0) << "CSD from AMediaFormat and MetaDataBase do not match";

    delete metaData;
    AMediaFormat_delete(csdData);
}

TEST_P(AvcCSDValidateTest, AvcValidateTest) {
    AMediaFormat *csdData = AMediaFormat_new();
    ASSERT_NE(csdData, nullptr) << "Failed to create AMedia format";

    bool status = MakeAVCCodecSpecificData(csdData, mInputBuffer, mInputBufferSize);
    ASSERT_FALSE(status) << "MakeAVCCodecSpecificData with AMediaFormat succeeds with invalid data";

    MetaDataBase *metaData = new MetaDataBase();
    ASSERT_NE(metaData, nullptr) << "Failed to create MetaData Base";

    status = MakeAVCCodecSpecificData(*metaData, mInputBuffer, mInputBufferSize);
    ASSERT_FALSE(status) << "MakeAVCCodecSpecificData with MetaDataBase succeeds with invalid data";
}

TEST_P(AacCSDTest, AacCSDValidationTest) {
    AMediaFormat *csdData = AMediaFormat_new();
    ASSERT_NE(csdData, nullptr) << "Failed to create AMedia format";

    ASSERT_GE(mAacSamplingFreqIndex, 0);
    ASSERT_LT(mAacSamplingFreqIndex, kMaxSamplingFreqIndex);
    bool status = MakeAACCodecSpecificData(csdData, mAacProfile, mAacSamplingFreqIndex,
                                           mAacChannelConfig);
    ASSERT_TRUE(status) << "Failed to make AAC CSD from AMediaFormat";

    int32_t sampleRate = -1;
    status = AMediaFormat_getInt32(csdData, AMEDIAFORMAT_KEY_SAMPLE_RATE, &sampleRate);
    ASSERT_TRUE(status) << "Failed to get sample rate";
    ASSERT_EQ(kSamplingFreq[mAacSamplingFreqIndex], sampleRate);

    int32_t channelCount = -1;
    status = AMediaFormat_getInt32(csdData, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &channelCount);
    ASSERT_TRUE(status) << "Failed to get channel count";
    ASSERT_EQ(channelCount, mAacChannelConfig);

    const char *mimeType = "";
    status = AMediaFormat_getString(csdData, AMEDIAFORMAT_KEY_MIME, &mimeType);
    ASSERT_TRUE(status) << "Failed to get the mime type";
    ASSERT_STREQ(mimeType, MEDIA_MIMETYPE_AUDIO_AAC);

    MetaDataBase *metaData = new MetaDataBase();
    ASSERT_NE(metaData, nullptr) << "Failed to create MetaData Base";

    status = MakeAACCodecSpecificData(*metaData, mAacProfile, mAacSamplingFreqIndex,
                                      mAacChannelConfig);
    ASSERT_TRUE(status) << "Failed to make AAC CSD from MetaDataBase";

    sampleRate = -1;
    status = metaData->findInt32(kKeySampleRate, &sampleRate);
    ASSERT_TRUE(status) << "Failed to get sampling rate";
    ASSERT_EQ(kSamplingFreq[mAacSamplingFreqIndex], sampleRate);

    channelCount = -1;
    status = metaData->findInt32(kKeyChannelCount, &channelCount);
    ASSERT_TRUE(status) << "Failed to get channel count";
    ASSERT_EQ(channelCount, mAacChannelConfig);

    mimeType = "";
    status = metaData->findCString(kKeyMIMEType, &mimeType);
    ASSERT_TRUE(status) << "Failed to get mime type";
    ASSERT_STREQ(mimeType, MEDIA_MIMETYPE_AUDIO_AAC);

    void *csdAMediaFormatBuffer = nullptr;
    size_t csdAMediaFormatSize = 0;
    status = AMediaFormat_getBuffer(csdData, AMEDIAFORMAT_KEY_CSD_0, &csdAMediaFormatBuffer,
                                    &csdAMediaFormatSize);
    ASSERT_TRUE(status) << "Failed to get the AMediaFormat CSD";
    ASSERT_GT(csdAMediaFormatSize, 0) << "CSD size must be greater than 0";
    ASSERT_NE(csdAMediaFormatBuffer, nullptr) << "Invalid CSD found";

    const void *csdMetaDataBaseBuffer;
    size_t csdMetaDataBaseSize = 0;
    uint32_t mediaType;
    status = metaData->findData(kKeyESDS, &mediaType, &csdMetaDataBaseBuffer, &csdMetaDataBaseSize);
    ASSERT_TRUE(status) << "Failed to get the ESDS data from MetaDataBase";
    ASSERT_GT(csdMetaDataBaseSize, 0) << "CSD size must be greater than 0";

    ESDS esds(csdMetaDataBaseBuffer, csdMetaDataBaseSize);
    status_t result = esds.getCodecSpecificInfo(&csdMetaDataBaseBuffer, &csdMetaDataBaseSize);
    ASSERT_EQ(result, (status_t)OK) << "Failed to get CSD from ESDS data";
    ASSERT_NE(csdMetaDataBaseBuffer, nullptr) << "Invalid CSD found";
    ASSERT_EQ(csdAMediaFormatSize, csdMetaDataBaseSize)
            << "CSD size do not match between AMediaFormat type and MetaDataBase type";

    int32_t memcmpResult =
            memcmp(csdAMediaFormatBuffer, csdMetaDataBaseBuffer, csdAMediaFormatSize);
    ASSERT_EQ(memcmpResult, 0) << "AMediaFormat and MetaDataBase CSDs do not match";

    AMediaFormat_delete(csdData);
    delete metaData;
}

TEST_P(AacADTSTest, AacADTSValidationTest) {
    MetaDataBase *metaData = new MetaDataBase();
    ASSERT_NE(metaData, nullptr) << "Failed to create meta data";

    bool status = MakeAACCodecSpecificData(*metaData, mInputBuffer, kAdtsCsdSize);
    ASSERT_TRUE(status) << "Failed to make AAC CSD from MetaDataBase";

    int32_t sampleRate = -1;
    status = metaData->findInt32(kKeySampleRate, &sampleRate);
    ASSERT_TRUE(status) << "Failed to get sampling rate";
    ASSERT_EQ(sampleRate, mAacSampleRate);

    int32_t channelCount = -1;
    status = metaData->findInt32(kKeyChannelCount, &channelCount);
    ASSERT_TRUE(status) << "Failed to get channel count";
    ASSERT_EQ(channelCount, mAacChannelCount);

    const char *mimeType = "";
    status = metaData->findCString(kKeyMIMEType, &mimeType);
    ASSERT_TRUE(status) << "Failed to get mime type";
    ASSERT_STREQ(mimeType, MEDIA_MIMETYPE_AUDIO_AAC);

    delete metaData;
}

TEST_P(AacCSDValidateTest, AacInvalidInputTest) {
    MetaDataBase *metaData = new MetaDataBase();
    ASSERT_NE(metaData, nullptr) << "Failed to create meta data";

    bool status = MakeAACCodecSpecificData(*metaData, mInputBuffer, kAdtsCsdSize);
    ASSERT_FALSE(status) << "MakeAACCodecSpecificData succeeds with invalid data";
}

TEST_P(VorbisTest, VorbisCommentTest) {
    string line;
    string tag;
    string key;
    string value;
    size_t commentLength;
    bool status;

    while (getline(mInfoFileStream, line)) {
        istringstream stringLine(line);
        stringLine >> tag >> key >> value >> commentLength;
        ASSERT_GT(commentLength, 0) << "Vorbis comment size must be greater than 0";

        string comment;
        string dataLine;

        getline(mInputFileStream, dataLine);
        istringstream dataStringLine(dataLine);
        dataStringLine >> comment;

        char *buffer = strndup(comment.c_str(), commentLength);
        ASSERT_NE(buffer, nullptr) << "Failed to allocate buffer of size: " << commentLength;

        AMediaFormat *fileMeta = AMediaFormat_new();
        ASSERT_NE(fileMeta, nullptr) << "Failed to create AMedia format";

        parseVorbisComment(fileMeta, buffer, commentLength);
        free(buffer);

        if (!strncasecmp(tag.c_str(), "ANDROID_HAPTIC", sizeof(tag))) {
            int32_t numChannelExpected = stoi(value);
            int32_t numChannelFound = -1;
            status = AMediaFormat_getInt32(fileMeta, key.c_str(), &numChannelFound);
            ASSERT_TRUE(status) << "Failed to get the channel count";
            ASSERT_EQ(numChannelExpected, numChannelFound);
        } else if (!strncasecmp(tag.c_str(), "ANDROID_LOOP", sizeof(tag))) {
            int32_t loopExpected = !value.compare("true");
            int32_t loopFound = -1;

            status = AMediaFormat_getInt32(fileMeta, "loop", &loopFound);
            ASSERT_TRUE(status) << "Failed to get the loop count";
            ASSERT_EQ(loopExpected, loopFound);
        } else {
            const char *tagValue = "";
            status = AMediaFormat_getString(fileMeta, key.c_str(), &tagValue);
            ASSERT_TRUE(status) << "Failed to get the tag value";
            ASSERT_STREQ(value.c_str(), tagValue);
        }
        AMediaFormat_delete(fileMeta);
    }
}

INSTANTIATE_TEST_SUITE_P(MetaDataUtilsTestAll, AvcCSDTest,
                         ::testing::Values(make_tuple("sps_pps_userdata.h264", 8, 8),
                                           make_tuple("sps_userdata_pps.h264", 8, 8),
                                           make_tuple("sps_pps_sps_pps.h264", 8, 8)));

// TODO(b/158067691): Add invalid test vectors with incomplete PPS or no PPS
INSTANTIATE_TEST_SUITE_P(MetaDataUtilsTestAll, AvcCSDValidateTest,
                         ::testing::Values("sps_pps_only_startcode.h264",
                                           "sps_incomplete_pps.h264",
                                           // TODO(b/158067691) "sps_pps_incomplete.h264",
                                           "randomdata.h264",
                                           // TODO(b/158067691) "sps.h264",
                                           "pps.h264"));

INSTANTIATE_TEST_SUITE_P(MetaDataUtilsTestAll, AacCSDTest,
                         ::testing::Values(make_tuple(AACObjectMain, 1, 1)));

INSTANTIATE_TEST_SUITE_P(MetaDataUtilsTestAll, AacADTSTest,
                         ::testing::Values(make_tuple("loudsoftaacadts", 1, 44100)));

INSTANTIATE_TEST_SUITE_P(MetaDataUtilsTestAll, AacCSDValidateTest,
                         ::testing::Values("loudsoftaacadts_invalidheader",
                                           "loudsoftaacadts_invalidprofile",
                                           "loudsoftaacadts_invalidchannelconfig"));

// TODO(b/157974508) Add test vector for vorbis thumbnail tag
// Info file contains TAG, Key, Value and size of the vorbis comment
INSTANTIATE_TEST_SUITE_P(
        MetaDataUtilsTestAll, VorbisTest,
        ::testing::Values(make_pair("vorbiscomment_sintel.dat", "vorbiscomment_sintel.info"),
                          make_pair("vorbiscomment_album.dat", "vorbiscomment_album.info"),
                          make_pair("vorbiscomment_loop.dat", "vorbiscomment_loop.info")));

int main(int argc, char **argv) {
    gEnv = new MetaDataUtilsTestEnvironment();
    ::testing::AddGlobalTestEnvironment(gEnv);
    ::testing::InitGoogleTest(&argc, argv);
    int status = gEnv->initFromOptions(argc, argv);
    if (status == 0) {
        status = RUN_ALL_TESTS();
        ALOGV("Test result = %d\n", status);
    }
    return status;
}
+73 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef __METADATA_UTILS_TEST_ENVIRONMENT_H__
#define __METADATA_UTILS_TEST_ENVIRONMENT_H__

#include <gtest/gtest.h>

#include <getopt.h>

using namespace std;

class MetaDataUtilsTestEnvironment : public::testing::Environment {
  public:
    MetaDataUtilsTestEnvironment() : res("/data/local/tmp/") {}

    // Parses the command line arguments
    int initFromOptions(int argc, char **argv);

    void setRes(const char *_res) { res = _res; }

    const string getRes() const { return res; }

  private:
    string res;
};

int MetaDataUtilsTestEnvironment::initFromOptions(int argc, char **argv) {
    static struct option options[] = {{"path", required_argument, 0, 'P'}, {0, 0, 0, 0}};

    while (true) {
        int index = 0;
        int c = getopt_long(argc, argv, "P:", options, &index);
        if (c == -1) {
            break;
        }

        switch (c) {
            case 'P': {
                setRes(optarg);
                break;
            }
            default:
                break;
        }
    }

    if (optind < argc) {
        fprintf(stderr,
                "unrecognized option: %s\n\n"
                "usage: %s <gtest options> <test options>\n\n"
                "test options are:\n\n"
                "-P, --path: Resource files directory location\n",
                argv[optind ?: 1], argv[0]);
        return 2;
    }
    return 0;
}

#endif  // __METADATA_UTILS_TEST_ENVIRONMENT_H__
+39 −0

File added.

Preview size limit exceeded, changes collapsed.