Merge changes I558b2d71,I1afce18b
* changes:
Set min_sdk_version to be part of mainline modules
Remove extractor-defaults_no-sanitizer
diff --git a/media/extractors/fuzzers/Android.bp b/media/extractors/fuzzers/Android.bp
index 7097b48..818e466 100644
--- a/media/extractors/fuzzers/Android.bp
+++ b/media/extractors/fuzzers/Android.bp
@@ -36,13 +36,13 @@
static_libs: [
"liblog",
"libstagefright_foundation",
- "libmedia",
+ "libmediandk_format",
+ "libmedia_ndkformatpriv",
],
shared_libs: [
"libutils",
"libbinder",
- "libmediandk",
],
/* GETEXTRACTORDEF is not defined as extractor library is not linked in the
@@ -50,6 +50,14 @@
* generated.
*/
allow_undefined_symbols: true,
+
+ host_supported: true,
+
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
cc_fuzz {
diff --git a/media/extractors/fuzzers/ExtractorFuzzerBase.cpp b/media/extractors/fuzzers/ExtractorFuzzerBase.cpp
index 291e020..1be8466 100644
--- a/media/extractors/fuzzers/ExtractorFuzzerBase.cpp
+++ b/media/extractors/fuzzers/ExtractorFuzzerBase.cpp
@@ -187,3 +187,15 @@
cTrack->stop(track);
free(cTrack);
}
+
+void ExtractorFuzzerBase::processData(const uint8_t* data, size_t size) {
+ if (setDataSource(data, size)) {
+ if (createExtractor()) {
+ getExtractorDef();
+ getMetadata();
+ extractTracks();
+ getTracksMetadata();
+ seekAndExtractTracks();
+ }
+ }
+}
diff --git a/media/extractors/fuzzers/aac_extractor_fuzzer.cpp b/media/extractors/fuzzers/aac_extractor_fuzzer.cpp
index 93665f0..98a6cc9 100644
--- a/media/extractors/fuzzers/aac_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/aac_extractor_fuzzer.cpp
@@ -46,17 +46,9 @@
return 0;
}
AacExtractor* extractor = new AacExtractor();
- if (!extractor) {
- return 0;
+ if (extractor) {
+ extractor->processData(data, size);
+ delete extractor;
}
- if (extractor->setDataSource(data, size)) {
- if (extractor->createExtractor()) {
- extractor->getExtractorDef();
- extractor->getMetadata();
- extractor->extractTracks();
- extractor->getTracksMetadata();
- }
- }
- delete extractor;
return 0;
}
diff --git a/media/extractors/fuzzers/amr_extractor_fuzzer.cpp b/media/extractors/fuzzers/amr_extractor_fuzzer.cpp
index b2f9261..6c9e1a5 100644
--- a/media/extractors/fuzzers/amr_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/amr_extractor_fuzzer.cpp
@@ -46,17 +46,9 @@
return 0;
}
AmrExtractor* extractor = new AmrExtractor();
- if (!extractor) {
- return 0;
+ if (extractor) {
+ extractor->processData(data, size);
+ delete extractor;
}
- if (extractor->setDataSource(data, size)) {
- if (extractor->createExtractor()) {
- extractor->getExtractorDef();
- extractor->getMetadata();
- extractor->extractTracks();
- extractor->getTracksMetadata();
- }
- }
- delete extractor;
return 0;
}
diff --git a/media/extractors/fuzzers/flac_extractor_fuzzer.cpp b/media/extractors/fuzzers/flac_extractor_fuzzer.cpp
index 61e41cf..8734d45 100644
--- a/media/extractors/fuzzers/flac_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/flac_extractor_fuzzer.cpp
@@ -46,17 +46,9 @@
return 0;
}
FlacExtractor* extractor = new FlacExtractor();
- if (!extractor) {
- return 0;
+ if (extractor) {
+ extractor->processData(data, size);
+ delete extractor;
}
- if (extractor->setDataSource(data, size)) {
- if (extractor->createExtractor()) {
- extractor->getExtractorDef();
- extractor->getMetadata();
- extractor->extractTracks();
- extractor->getTracksMetadata();
- }
- }
- delete extractor;
return 0;
}
diff --git a/media/extractors/fuzzers/include/ExtractorFuzzerBase.h b/media/extractors/fuzzers/include/ExtractorFuzzerBase.h
index 86c70fc..6a2a1c1 100644
--- a/media/extractors/fuzzers/include/ExtractorFuzzerBase.h
+++ b/media/extractors/fuzzers/include/ExtractorFuzzerBase.h
@@ -70,6 +70,8 @@
void seekAndExtractTracks();
+ void processData(const uint8_t* data, size_t size);
+
protected:
class BufferSource : public DataSource {
public:
diff --git a/media/extractors/fuzzers/mkv_extractor_fuzzer.cpp b/media/extractors/fuzzers/mkv_extractor_fuzzer.cpp
index 14274b7..eceb93f 100644
--- a/media/extractors/fuzzers/mkv_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/mkv_extractor_fuzzer.cpp
@@ -46,17 +46,9 @@
return 0;
}
MKVExtractor* extractor = new MKVExtractor();
- if (!extractor) {
- return 0;
+ if (extractor) {
+ extractor->processData(data, size);
+ delete extractor;
}
- if (extractor->setDataSource(data, size)) {
- if (extractor->createExtractor()) {
- extractor->getExtractorDef();
- extractor->getMetadata();
- extractor->extractTracks();
- extractor->getTracksMetadata();
- }
- }
- delete extractor;
return 0;
}
diff --git a/media/extractors/fuzzers/mp3_extractor_fuzzer.cpp b/media/extractors/fuzzers/mp3_extractor_fuzzer.cpp
index 71c154b..9a47c18 100644
--- a/media/extractors/fuzzers/mp3_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/mp3_extractor_fuzzer.cpp
@@ -46,17 +46,9 @@
return 0;
}
Mp3Extractor* extractor = new Mp3Extractor();
- if (!extractor) {
- return 0;
+ if (extractor) {
+ extractor->processData(data, size);
+ delete extractor;
}
- if (extractor->setDataSource(data, size)) {
- if (extractor->createExtractor()) {
- extractor->getExtractorDef();
- extractor->getMetadata();
- extractor->extractTracks();
- extractor->getTracksMetadata();
- }
- }
- delete extractor;
return 0;
}
diff --git a/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp b/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp
index d2cc133..3903519 100644
--- a/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp
@@ -48,17 +48,9 @@
return 0;
}
MP4Extractor* extractor = new MP4Extractor();
- if (!extractor) {
- return 0;
+ if (extractor) {
+ extractor->processData(data, size);
+ delete extractor;
}
- if (extractor->setDataSource(data, size)) {
- if (extractor->createExtractor()) {
- extractor->getExtractorDef();
- extractor->getMetadata();
- extractor->extractTracks();
- extractor->getTracksMetadata();
- }
- }
- delete extractor;
return 0;
}
diff --git a/media/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp b/media/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp
index c34ffa0..240ef66 100644
--- a/media/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/mpeg2_extractor_fuzzer.cpp
@@ -54,17 +54,9 @@
return 0;
}
MPEG2Extractor* extractor = new MPEG2Extractor();
- if (!extractor) {
- return 0;
+ if (extractor) {
+ extractor->processData(data, size);
+ delete extractor;
}
- if (extractor->setDataSource(data, size)) {
- if (extractor->createExtractor()) {
- extractor->getExtractorDef();
- extractor->extractTracks();
- extractor->extractTracks();
- extractor->getTracksMetadata();
- }
- }
- delete extractor;
return 0;
}
diff --git a/media/extractors/fuzzers/ogg_extractor_fuzzer.cpp b/media/extractors/fuzzers/ogg_extractor_fuzzer.cpp
index 033c50b..bd2fcc5 100644
--- a/media/extractors/fuzzers/ogg_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/ogg_extractor_fuzzer.cpp
@@ -46,17 +46,9 @@
return 0;
}
OGGExtractor* extractor = new OGGExtractor();
- if (!extractor) {
- return 0;
+ if (extractor) {
+ extractor->processData(data, size);
+ delete extractor;
}
- if (extractor->setDataSource(data, size)) {
- if (extractor->createExtractor()) {
- extractor->getExtractorDef();
- extractor->getMetadata();
- extractor->extractTracks();
- extractor->getTracksMetadata();
- }
- }
- delete extractor;
return 0;
}
diff --git a/media/extractors/fuzzers/wav_extractor_fuzzer.cpp b/media/extractors/fuzzers/wav_extractor_fuzzer.cpp
index 1397122..cb11ebd 100644
--- a/media/extractors/fuzzers/wav_extractor_fuzzer.cpp
+++ b/media/extractors/fuzzers/wav_extractor_fuzzer.cpp
@@ -46,17 +46,9 @@
return 0;
}
wavExtractor* extractor = new wavExtractor();
- if (!extractor) {
- return 0;
+ if (extractor) {
+ extractor->processData(data, size);
+ delete extractor;
}
- if (extractor->setDataSource(data, size)) {
- if (extractor->createExtractor()) {
- extractor->getExtractorDef();
- extractor->getMetadata();
- extractor->extractTracks();
- extractor->getTracksMetadata();
- }
- }
- delete extractor;
return 0;
}
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index e2795ac..92df3b7 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -40,6 +40,12 @@
"libstagefright_foundation",
"libutils"
],
+ host_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
}
cc_library_static {
diff --git a/media/libstagefright/tests/ESDS/Android.bp b/media/libstagefright/tests/ESDS/Android.bp
new file mode 100644
index 0000000..1ad1a64
--- /dev/null
+++ b/media/libstagefright/tests/ESDS/Android.bp
@@ -0,0 +1,51 @@
+/*
+ * 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: "ESDSTest",
+ gtest: true,
+
+ srcs: [
+ "ESDSTest.cpp",
+ ],
+
+ shared_libs: [
+ "libbinder",
+ "libdatasource",
+ "liblog",
+ "libmedia",
+ "libstagefright",
+ "libstagefright_foundation",
+ "libutils",
+ ],
+
+ static_libs: [
+ "libstagefright_esds",
+ ],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+
+ sanitize: {
+ cfi: true,
+ misc_undefined: [
+ "unsigned-integer-overflow",
+ "signed-integer-overflow",
+ ],
+ },
+}
diff --git a/media/libstagefright/tests/ESDS/AndroidTest.xml b/media/libstagefright/tests/ESDS/AndroidTest.xml
new file mode 100644
index 0000000..a4fbc7f
--- /dev/null
+++ b/media/libstagefright/tests/ESDS/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?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 ESDS unit test">
+ <option name="test-suite-tag" value="ESDSTest" />
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="ESDSTest->/data/local/tmp/ESDSTest" />
+ <option name="push-file"
+ key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/ESDS/ESDSTestRes-1.0.zip?unzip=true"
+ value="/data/local/tmp/ESDSTestRes/" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="ESDSTest" />
+ <option name="native-test-flag" value="-P /data/local/tmp/ESDSTestRes/" />
+ </test>
+</configuration>
diff --git a/media/libstagefright/tests/ESDS/ESDSTest.cpp b/media/libstagefright/tests/ESDS/ESDSTest.cpp
new file mode 100644
index 0000000..101e00c
--- /dev/null
+++ b/media/libstagefright/tests/ESDS/ESDSTest.cpp
@@ -0,0 +1,210 @@
+/*
+ * 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 "ESDSTest"
+#include <utils/Log.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <fstream>
+
+#include <ESDS.h>
+#include <binder/ProcessState.h>
+#include <datasource/FileSource.h>
+#include <media/stagefright/MediaExtractorFactory.h>
+#include <media/stagefright/MetaData.h>
+
+#include "ESDSTestEnvironment.h"
+
+using namespace android;
+
+static ESDSTestEnvironment *gEnv = nullptr;
+
+struct ESDSParams {
+ const char *inputFile;
+ int32_t objectTypeIndication;
+ const char *codecSpecificInfoData;
+ int32_t codecSpecificInfoDataSize;
+ int32_t bitrateMax;
+ int32_t bitrateAvg;
+};
+
+class ESDSUnitTest : public ::testing::TestWithParam<tuple<
+ /* InputFile */ const char *,
+ /* ObjectTypeIndication */ int32_t,
+ /* CodecSpecificInfoData */ const char *,
+ /* CodecSpecificInfoDataSize */ int32_t,
+ /* BitrateMax */ int32_t,
+ /* BitrateAvg */ int32_t>> {
+ public:
+ ESDSUnitTest() : mESDSData(nullptr) {
+ mESDSParams.inputFile = get<0>(GetParam());
+ mESDSParams.objectTypeIndication = get<1>(GetParam());
+ mESDSParams.codecSpecificInfoData = get<2>(GetParam());
+ mESDSParams.codecSpecificInfoDataSize = get<3>(GetParam());
+ mESDSParams.bitrateMax = get<4>(GetParam());
+ mESDSParams.bitrateAvg = get<5>(GetParam());
+ };
+
+ virtual void TearDown() override {
+ if (mDataSource) mDataSource.clear();
+ if (mInputFp) {
+ fclose(mInputFp);
+ mInputFp = nullptr;
+ }
+ }
+
+ virtual void SetUp() override { ASSERT_NO_FATAL_FAILURE(readESDSData()); }
+ const void *mESDSData;
+ size_t mESDSSize;
+ ESDSParams mESDSParams;
+
+ private:
+ void readESDSData() {
+ string inputFile = gEnv->getRes() + mESDSParams.inputFile;
+ mInputFp = fopen(inputFile.c_str(), "rb");
+ ASSERT_NE(mInputFp, nullptr) << "File open failed for file: " << inputFile;
+ int32_t fd = fileno(mInputFp);
+ ASSERT_GE(fd, 0) << "File descriptor invalid for file: " << inputFile;
+
+ struct stat buf;
+ status_t status = stat(inputFile.c_str(), &buf);
+ ASSERT_EQ(status, 0) << "Failed to get properties of input file: " << mESDSParams.inputFile;
+ size_t fileSize = buf.st_size;
+
+ mDataSource = new FileSource(dup(fd), 0, fileSize);
+ ASSERT_NE(mDataSource, nullptr) << "Unable to create data source for file: " << inputFile;
+
+ sp<IMediaExtractor> extractor = MediaExtractorFactory::Create(mDataSource);
+ if (extractor == nullptr) {
+ mDataSource.clear();
+ ASSERT_TRUE(false) << "Unable to create extractor for file: " << inputFile;
+ }
+
+ size_t numTracks = extractor->countTracks();
+ ASSERT_GT(numTracks, 0) << "No tracks in file: " << inputFile;
+ ASSERT_TRUE(esdsDataPresent(numTracks, extractor))
+ << "Unable to find esds in any track in file: " << inputFile;
+ }
+
+ bool esdsDataPresent(size_t numTracks, sp<IMediaExtractor> extractor) {
+ bool foundESDS = false;
+ uint32_t type;
+ for (size_t i = 0; i < numTracks; ++i) {
+ sp<MetaData> trackMeta = extractor->getTrackMetaData(i);
+ if (trackMeta != nullptr &&
+ trackMeta->findData(kKeyESDS, &type, &mESDSData, &mESDSSize)) {
+ trackMeta->clear();
+ foundESDS = true;
+ break;
+ }
+ }
+ return foundESDS;
+ }
+
+ FILE *mInputFp;
+ sp<DataSource> mDataSource;
+};
+
+TEST_P(ESDSUnitTest, InvalidDataTest) {
+ void *invalidData = calloc(mESDSSize, 1);
+ ASSERT_NE(invalidData, nullptr) << "Unable to allocate memory";
+ ESDS esds(invalidData, mESDSSize);
+ free(invalidData);
+ ASSERT_NE(esds.InitCheck(), OK) << "invalid ESDS data accepted";
+}
+
+TEST(ESDSSanityUnitTest, ConstructorSanityTest) {
+ void *invalidData = malloc(1);
+ ASSERT_NE(invalidData, nullptr) << "Unable to allocate memory";
+ ESDS esds_zero(invalidData, 0);
+ free(invalidData);
+ ASSERT_NE(esds_zero.InitCheck(), OK) << "invalid ESDS data accepted";
+
+ ESDS esds_null(NULL, 0);
+ ASSERT_NE(esds_null.InitCheck(), OK) << "invalid ESDS data accepted";
+}
+
+TEST_P(ESDSUnitTest, CreateAndDestroyTest) {
+ ESDS esds(mESDSData, mESDSSize);
+ ASSERT_EQ(esds.InitCheck(), OK) << "ESDS data invalid";
+}
+
+TEST_P(ESDSUnitTest, ObjectTypeIndicationTest) {
+ ESDS esds(mESDSData, mESDSSize);
+ ASSERT_EQ(esds.InitCheck(), OK) << "ESDS data invalid";
+ uint8_t objectTypeIndication;
+ status_t status = esds.getObjectTypeIndication(&objectTypeIndication);
+ ASSERT_EQ(status, OK) << "ESDS objectTypeIndication data invalid";
+ ASSERT_EQ(objectTypeIndication, mESDSParams.objectTypeIndication)
+ << "ESDS objectTypeIndication data doesn't match";
+}
+
+TEST_P(ESDSUnitTest, CodecSpecificInfoTest) {
+ ESDS esds(mESDSData, mESDSSize);
+ ASSERT_EQ(esds.InitCheck(), OK) << "ESDS data invalid";
+ status_t status;
+ const void *codecSpecificInfo;
+ size_t codecSpecificInfoSize;
+ status = esds.getCodecSpecificInfo(&codecSpecificInfo, &codecSpecificInfoSize);
+ ASSERT_EQ(status, OK) << "ESDS getCodecSpecificInfo data invalid";
+ ASSERT_EQ(mESDSParams.codecSpecificInfoDataSize, codecSpecificInfoSize)
+ << "CodecSpecificInfo data doesn't match";
+ status = memcmp(codecSpecificInfo, mESDSParams.codecSpecificInfoData, codecSpecificInfoSize);
+ ASSERT_EQ(status, 0) << "CodecSpecificInfo data doesn't match";
+}
+
+TEST_P(ESDSUnitTest, GetBitrateTest) {
+ ESDS esds(mESDSData, mESDSSize);
+ ASSERT_EQ(esds.InitCheck(), OK) << "ESDS data invalid";
+ uint32_t bitrateMax;
+ uint32_t bitrateAvg;
+ status_t status = esds.getBitRate(&bitrateMax, &bitrateAvg);
+ ASSERT_EQ(status, OK) << "ESDS bitRate data invalid";
+ ASSERT_EQ(bitrateMax, mESDSParams.bitrateMax) << "ESDS bitrateMax doesn't match";
+ ASSERT_EQ(bitrateAvg, mESDSParams.bitrateAvg) << "ESDS bitrateAvg doesn't match";
+ ASSERT_LE(bitrateAvg, bitrateMax) << "ESDS bitrateMax is less than bitrateAvg";
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ ESDSUnitTestAll, ESDSUnitTest,
+ ::testing::Values(
+ // InputFile, ObjectTypeIndication, CodecSpecificInfoData,
+ // CodecSpecificInfoDataSize, BitrateMax, BitrateAvg
+ make_tuple("video_176x144_3gp_h263_56kbps_12fps_aac_stereo_128kbps_22050hz.3gp", 64,
+ "\x13\x90", 2, 131072, 0),
+ make_tuple("video_1280x720_mp4_mpeg2_3000kbps_30fps_aac_stereo_128kbps_48000hz.mp4",
+ 97,
+ "\x00\x00\x01\xB3\x50\x02\xD0\x35\xFF\xFF\xE1\xA0\x00\x00\x01\xB5\x15"
+ "\x6A\x00\x01\x00\x00",
+ 22, 3415452, 3415452),
+ make_tuple("video_176x144_3gp_h263_56kbps_25fps_aac_mono_24kbps_11025hz.3gp", 64,
+ "\x15\x08", 2, 24576, 0)));
+
+int main(int argc, char **argv) {
+ // MediaExtractor needs binder thread pool
+ ProcessState::self()->startThreadPool();
+ gEnv = new ESDSTestEnvironment();
+ ::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;
+}
diff --git a/media/libstagefright/tests/ESDS/ESDSTestEnvironment.h b/media/libstagefright/tests/ESDS/ESDSTestEnvironment.h
new file mode 100644
index 0000000..4ca2303
--- /dev/null
+++ b/media/libstagefright/tests/ESDS/ESDSTestEnvironment.h
@@ -0,0 +1,72 @@
+/*
+ * 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 __ESDS_TEST_ENVIRONMENT_H__
+#define __ESDS_TEST_ENVIRONMENT_H__
+
+#include <gtest/gtest.h>
+
+#include <getopt.h>
+
+using namespace std;
+
+class ESDSTestEnvironment : public ::testing::Environment {
+ public:
+ ESDSTestEnvironment() : 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 ESDSTestEnvironment::initFromOptions(int argc, char **argv) {
+ static struct option options[] = {{"res", 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 // __ESDS_TEST_ENVIRONMENT_H__
diff --git a/media/libstagefright/tests/ESDS/README.md b/media/libstagefright/tests/ESDS/README.md
new file mode 100644
index 0000000..100fb86
--- /dev/null
+++ b/media/libstagefright/tests/ESDS/README.md
@@ -0,0 +1,40 @@
+## Media Testing ##
+---
+#### ESDS Unit Test :
+The ESDS Unit Test Suite validates the ESDS class available in libstagefright.
+
+Run the following steps to build the test suite:
+```
+m ESDSTest
+```
+
+The 32-bit binaries will be created in the following path : ${OUT}/data/nativetest/
+
+The 64-bit binaries will be created in the following path : ${OUT}/data/nativetest64/
+
+To test 64-bit binary push binaries from nativetest64.
+```
+adb push ${OUT}/data/nativetest64/ESDSTest/ESDSTest /data/local/tmp/
+```
+
+To test 32-bit binary push binaries from nativetest.
+```
+adb push ${OUT}/data/nativetest/ESDSTest/ESDSTest /data/local/tmp/
+```
+
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/ESDS/ESDSTestRes-1.0.zip)
+Download, unzip and push these files into device for testing.
+
+```
+adb push ESDSTestRes /data/local/tmp/
+```
+
+usage: ESDSTest -P \<path_to_folder\>
+```
+adb shell /data/local/tmp/ESDSTest -P /data/local/tmp/ESDSTestRes/
+```
+Alternatively, the test can also be run using atest command.
+
+```
+atest ESDSTest -- --enable-module-dynamic-download=true
+```