Merge "Update timedtext unittest"
diff --git a/media/extractors/fuzzers/Android.bp b/media/extractors/fuzzers/Android.bp
new file mode 100644
index 0000000..5fb8155
--- /dev/null
+++ b/media/extractors/fuzzers/Android.bp
@@ -0,0 +1,83 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+cc_library {
+ name: "libextractorfuzzerbase",
+
+ srcs: [
+ "ExtractorFuzzerBase.cpp",
+ ],
+
+ local_include_dirs: [
+ "include",
+ ],
+
+ export_include_dirs: [
+ "include",
+ ],
+
+ static_libs: [
+ "liblog",
+ "libstagefright_foundation",
+ "libmedia",
+ ],
+
+ shared_libs: [
+ "libutils",
+ "libbinder",
+ "libmediandk",
+ ],
+
+ /* GETEXTRACTORDEF is not defined as extractor library is not linked in the
+ * base class. It will be included when the extractor fuzzer binary is
+ * generated.
+ */
+ allow_undefined_symbols: true,
+}
+
+cc_fuzz {
+ name: "mp4_extractor_fuzzer",
+
+ srcs: [
+ "mp4_extractor_fuzzer.cpp",
+ ],
+
+ include_dirs: [
+ "frameworks/av/media/extractors/mp4",
+ ],
+
+ static_libs: [
+ "liblog",
+ "libstagefright_foundation",
+ "libmedia",
+ "libextractorfuzzerbase",
+ "libstagefright_id3",
+ "libstagefright_esds",
+ "libmp4extractor",
+ ],
+
+ shared_libs: [
+ "libutils",
+ "libmediandk",
+ "libbinder",
+ ],
+
+ dictionary: "mp4_extractor_fuzzer.dict",
+}
diff --git a/media/extractors/fuzzers/ExtractorFuzzerBase.cpp b/media/extractors/fuzzers/ExtractorFuzzerBase.cpp
new file mode 100644
index 0000000..cbd6395
--- /dev/null
+++ b/media/extractors/fuzzers/ExtractorFuzzerBase.cpp
@@ -0,0 +1,118 @@
+/*
+ * 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 "ExtractorFuzzerBase"
+#include <utils/Log.h>
+
+#include "ExtractorFuzzerBase.h"
+
+using namespace android;
+
+bool ExtractorFuzzerBase::setDataSource(const uint8_t* data, size_t size) {
+ if ((!data) || (size == 0)) {
+ return false;
+ }
+ mBufferSource = new BufferSource(data, size);
+ mDataSource = reinterpret_cast<DataSource*>(mBufferSource.get());
+ if (!mDataSource) {
+ return false;
+ }
+ return true;
+}
+
+bool ExtractorFuzzerBase::getExtractorDef() {
+ float confidence;
+ void* meta = nullptr;
+ FreeMetaFunc freeMeta = nullptr;
+
+ ExtractorDef extractorDef = GETEXTRACTORDEF();
+ if (extractorDef.def_version == EXTRACTORDEF_VERSION_NDK_V1) {
+ extractorDef.u.v2.sniff(mDataSource->wrap(), &confidence, &meta, &freeMeta);
+ } else if (extractorDef.def_version == EXTRACTORDEF_VERSION_NDK_V2) {
+ extractorDef.u.v3.sniff(mDataSource->wrap(), &confidence, &meta, &freeMeta);
+ }
+
+ if (meta != nullptr && freeMeta != nullptr) {
+ freeMeta(meta);
+ }
+
+ return true;
+}
+
+bool ExtractorFuzzerBase::extractTracks() {
+ MediaBufferGroup* bufferGroup = new MediaBufferGroup();
+ if (!bufferGroup) {
+ return false;
+ }
+ for (size_t trackIndex = 0; trackIndex < mExtractor->countTracks(); ++trackIndex) {
+ MediaTrackHelper* track = mExtractor->getTrack(trackIndex);
+ if (!track) {
+ continue;
+ }
+ extractTrack(track, bufferGroup);
+ delete track;
+ }
+ delete bufferGroup;
+ return true;
+}
+
+void ExtractorFuzzerBase::extractTrack(MediaTrackHelper* track, MediaBufferGroup* bufferGroup) {
+ CMediaTrack* cTrack = wrap(track);
+ if (!cTrack) {
+ return;
+ }
+
+ media_status_t status = cTrack->start(track, bufferGroup->wrap());
+ if (status != AMEDIA_OK) {
+ free(cTrack);
+ return;
+ }
+
+ do {
+ MediaBufferHelper* buffer = nullptr;
+ status = track->read(&buffer);
+ if (buffer) {
+ buffer->release();
+ }
+ } while (status == AMEDIA_OK);
+
+ cTrack->stop(track);
+ free(cTrack);
+}
+
+bool ExtractorFuzzerBase::getTracksMetadata() {
+ AMediaFormat* format = AMediaFormat_new();
+ uint32_t flags = MediaExtractorPluginHelper::kIncludeExtensiveMetaData;
+
+ for (size_t trackIndex = 0; trackIndex < mExtractor->countTracks(); ++trackIndex) {
+ mExtractor->getTrackMetaData(format, trackIndex, flags);
+ }
+
+ AMediaFormat_delete(format);
+ return true;
+}
+
+bool ExtractorFuzzerBase::getMetadata() {
+ AMediaFormat* format = AMediaFormat_new();
+ mExtractor->getMetaData(format);
+ AMediaFormat_delete(format);
+ return true;
+}
+
+void ExtractorFuzzerBase::setDataSourceFlags(uint32_t flags) {
+ mBufferSource->setFlags(flags);
+}
diff --git a/media/extractors/fuzzers/README.md b/media/extractors/fuzzers/README.md
new file mode 100644
index 0000000..a6c17c0
--- /dev/null
+++ b/media/extractors/fuzzers/README.md
@@ -0,0 +1,54 @@
+# Fuzzer for extractors
+
+## Table of contents
+1. [libextractorfuzzerbase](#ExtractorFuzzerBase)
+2. [libmp4extractor](#mp4ExtractorFuzzer)
+
+# <a name="ExtractorFuzzerBase"></a> Fuzzer for libextractorfuzzerbase
+All the extractors have a common API - creating a data source, extraction
+of all the tracks, etc. These common APIs have been abstracted in a base class
+called `ExtractorFuzzerBase` to ensure code is reused between fuzzer plugins.
+
+Additionally, `ExtractorFuzzerBase` also has support for memory based buffer
+`BufferSource` since the fuzzing engine feeds data using memory buffers and
+usage of standard data source objects like FileSource, HTTPSource, etc. is
+not feasible.
+
+# <a name="mp4ExtractorFuzzer"></a> Fuzzer for libmp4extractor
+
+## Plugin Design Considerations
+The fuzzer plugin for MP4 extractor uses the `ExtractorFuzzerBase` class and
+implements only the `createExtractor` to create the MP4 extractor class.
+
+##### Maximize code coverage
+Dict file (dictionary file) is created for MP4 to ensure that the required MP4
+atoms are present in every input file that goes to the fuzzer.
+This ensures that larger code gets covered as a range of MP4 atoms will be
+present in the input data.
+
+
+## Build
+
+This describes steps to build mp4_extractor_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) mp4_extractor_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some MP4 files to that folder
+Push this directory to device.
+
+To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/mp4_extractor_fuzzer/mp4_extractor_fuzzer CORPUS_DIR
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/media/extractors/fuzzers/include/ExtractorFuzzerBase.h b/media/extractors/fuzzers/include/ExtractorFuzzerBase.h
new file mode 100644
index 0000000..abf362b
--- /dev/null
+++ b/media/extractors/fuzzers/include/ExtractorFuzzerBase.h
@@ -0,0 +1,130 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#ifndef __EXTRACTOR_FUZZER_BASE_H__
+#define __EXTRACTOR_FUZZER_BASE_H__
+
+#include <media/DataSource.h>
+#include <media/MediaExtractorPluginHelper.h>
+#include <media/stagefright/MediaBufferGroup.h>
+
+extern "C" {
+android::ExtractorDef GETEXTRACTORDEF();
+}
+
+namespace android {
+
+class ExtractorFuzzerBase {
+ public:
+ ExtractorFuzzerBase() = default;
+ virtual ~ExtractorFuzzerBase() {
+ if (mExtractor) {
+ delete mExtractor;
+ mExtractor = nullptr;
+ }
+ if (mBufferSource) {
+ mBufferSource.clear();
+ mBufferSource = nullptr;
+ }
+ }
+
+ /** Function to create the media extractor component.
+ * To be implemented by the derived class.
+ */
+ virtual bool createExtractor() = 0;
+
+ /** Parent class functions to be reused by derived class.
+ * These are common for all media extractor components.
+ */
+ bool setDataSource(const uint8_t* data, size_t size);
+
+ bool getExtractorDef();
+
+ bool extractTracks();
+
+ bool getMetadata();
+
+ bool getTracksMetadata();
+
+ void setDataSourceFlags(uint32_t flags);
+
+ protected:
+ class BufferSource : public DataSource {
+ public:
+ BufferSource(const uint8_t* data, size_t length) : mData(data), mLength(length) {}
+ virtual ~BufferSource() { mData = nullptr; }
+
+ void setFlags(uint32_t flags) { mFlags = flags; }
+
+ uint32_t flags() { return mFlags; }
+
+ status_t initCheck() const { return mData != nullptr ? OK : NO_INIT; }
+
+ ssize_t readAt(off64_t offset, void* data, size_t size) {
+ if (!mData) {
+ return NO_INIT;
+ }
+
+ Mutex::Autolock autoLock(mLock);
+ if ((offset >= static_cast<off64_t>(mLength)) || (offset < 0)) {
+ return 0; // read beyond bounds.
+ }
+ size_t numAvailable = mLength - static_cast<size_t>(offset);
+ if (size > numAvailable) {
+ size = numAvailable;
+ }
+ return readAt_l(offset, data, size);
+ }
+
+ status_t getSize(off64_t* size) {
+ if (!mData) {
+ return NO_INIT;
+ }
+
+ Mutex::Autolock autoLock(mLock);
+ *size = static_cast<off64_t>(mLength);
+ return OK;
+ }
+
+ protected:
+ ssize_t readAt_l(off64_t offset, void* data, size_t size) {
+ void* result = memcpy(data, mData + offset, size);
+ return result != nullptr ? size : 0;
+ }
+
+ const uint8_t* mData = nullptr;
+ size_t mLength = 0;
+ Mutex mLock;
+ uint32_t mFlags = 0;
+
+ private:
+ DISALLOW_EVIL_CONSTRUCTORS(BufferSource);
+ };
+
+ sp<BufferSource> mBufferSource;
+ DataSource* mDataSource = nullptr;
+ MediaExtractorPluginHelper* mExtractor = nullptr;
+
+ virtual void extractTrack(MediaTrackHelper* track, MediaBufferGroup* bufferGroup);
+};
+
+} // namespace android
+
+#endif // __EXTRACTOR_FUZZER_BASE_H__
diff --git a/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp b/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp
new file mode 100644
index 0000000..d2cc133
--- /dev/null
+++ b/media/extractors/fuzzers/mp4_extractor_fuzzer.cpp
@@ -0,0 +1,64 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "ExtractorFuzzerBase.h"
+
+#include "MPEG4Extractor.h"
+#include "SampleTable.h"
+
+using namespace android;
+
+class MP4Extractor : public ExtractorFuzzerBase {
+ public:
+ MP4Extractor() = default;
+ ~MP4Extractor() = default;
+
+ bool createExtractor();
+};
+
+bool MP4Extractor::createExtractor() {
+ mExtractor = new MPEG4Extractor(new DataSourceHelper(mDataSource->wrap()));
+ if (!mExtractor) {
+ return false;
+ }
+ mExtractor->name();
+ setDataSourceFlags(DataSourceBase::kWantsPrefetching | DataSourceBase::kIsCachingDataSource);
+ return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ if ((!data) || (size == 0)) {
+ return 0;
+ }
+ MP4Extractor* extractor = new MP4Extractor();
+ if (!extractor) {
+ return 0;
+ }
+ 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.dict b/media/extractors/fuzzers/mp4_extractor_fuzzer.dict
new file mode 100644
index 0000000..42a86f3
--- /dev/null
+++ b/media/extractors/fuzzers/mp4_extractor_fuzzer.dict
@@ -0,0 +1,248 @@
+# MP4 Atoms/Boxes
+kw1="ftyp"
+kw2="free"
+kw3="mdat"
+kw4="moov"
+kw5="mvhd"
+kw6="trak"
+kw7="tkhd"
+kw8="edts"
+kw9="elst"
+kw10="mdia"
+kw11="mdhd"
+kw12="hdlr"
+kw13="minf"
+kw14="vmhd"
+kw15="dinf"
+kw16="dref"
+kw17="url "
+kw18="stbl"
+kw19="stsd"
+kw20="avc1"
+kw21="avcC"
+kw22="stts"
+kw23="stss"
+kw24="ctts"
+kw25="stsc"
+kw26="stsz"
+kw27="stco"
+kw28="mp4a"
+kw29="esds"
+kw30="udta"
+kw31="meta"
+kw32="ilst"
+kw33="samr"
+kw34="sawb"
+kw35="ec-3"
+kw36="mp4v"
+kw37="s263"
+kw38="h263"
+kw39="H263"
+kw40="avc1"
+kw41="hvc1"
+kw42="hev1"
+kw43="ac-4"
+kw44="Opus"
+kw45="twos"
+kw46="sowt"
+kw47="alac"
+kw48="fLaC"
+kw49="av01"
+kw50=".mp3"
+kw51="keys"
+kw52="cprt"
+kw53="covr"
+kw54="mvex"
+kw55="moof"
+kw56="traf"
+kw57="mfra"
+kw58="sinf"
+kw59="schi"
+kw60="wave"
+kw61="schm"
+kw62="cbc1"
+kw63="cbcs"
+kw64="cenc"
+kw65="cens"
+kw66="frma"
+kw67="tenc"
+kw68="tref"
+kw69="thmb"
+kw70="pssh"
+kw71="mett"
+kw72="enca"
+kw73="encv"
+kw74="co64"
+kw75="stz2"
+kw76="\251xyz"
+kw77="btrt"
+kw78="hvcC"
+kw79="av1C"
+kw80="d263"
+kw81="iloc"
+kw82="iinf"
+kw83="iprp"
+kw84="pitm"
+kw85="idat"
+kw86="iref"
+kw87="ipro"
+kw88="mean"
+kw89="name"
+kw90="data"
+kw91="mehd"
+kw92="text"
+kw93="sbtl"
+kw94="trex"
+kw95="tx3g"
+kw96="colr"
+kw97="titl"
+kw98="perf"
+kw99="auth"
+kw100="gnre"
+kw101="albm"
+kw102="yrrc"
+kw103="ID32"
+kw104="----"
+kw105="sidx"
+kw106="ac-3"
+kw107="qt "
+kw108="mif1"
+kw109="heic"
+kw110="dac4"
+kw111="dec3"
+kw112="dac3"
+kw113="\251alb"
+kw114="\251ART"
+kw115="aART"
+kw116="\251day"
+kw117="\251nam"
+kw118="\251wrt"
+kw119="\251gen"
+kw120="cpil"
+kw121="trkn"
+kw122="disk"
+kw123="nclx"
+kw124="nclc"
+kw125="tfhd"
+kw126="trun"
+kw127="saiz"
+kw128="saio"
+kw129="senc"
+kw130="isom"
+kw131="iso2"
+kw132="3gp4"
+kw133="mp41"
+kw134="mp42"
+kw135="dash"
+kw136="nvr1"
+kw137="MSNV"
+kw138="wmf "
+kw139="3g2a"
+kw140="3g2b"
+kw141="msf1"
+kw142="hevc"
+kw143="pdin"
+kw144="trgr"
+kw145="smhd"
+kw146="hmhd"
+kw147="nmhd"
+kw148="cslg"
+kw149="stsh"
+kw150="padb"
+kw151="stdp"
+kw152="sdtp"
+kw153="sbgp"
+kw154="sgpd"
+kw155="subs"
+kw156="leva"
+kw157="mfhd"
+kw158="tfdt"
+kw159="tfra"
+kw160="mfro"
+kw161="skip"
+kw162="tsel"
+kw163="strk"
+kw164="stri"
+kw165="strd"
+kw166="xml "
+kw167="bxml"
+kw168="fiin"
+kw169="paen"
+kw170="fire"
+kw171="fpar"
+kw172="fecr"
+kw173="segr"
+kw174="gitn"
+kw175="meco"
+kw176="mere"
+kw177="styp"
+kw178="ssix"
+kw179="prft"
+kw180="hint"
+kw181="cdsc"
+kw182="hind"
+kw183="vdep"
+kw184="vplx"
+kw185="msrc"
+kw186="urn "
+kw187="enct"
+kw188="encs"
+kw189="rinf"
+kw190="srpp"
+kw191="stsg"
+kw192="stvi"
+kw193="tims"
+kw194="tsro"
+kw195="snro"
+kw196="rtp "
+kw197="srtp"
+kw198="rtpo"
+kw199="hnti"
+kw200="sdp "
+kw201="trpy"
+kw202="nump"
+kw203="tpyl"
+kw204="totl"
+kw205="npck"
+kw206="tpay"
+kw207="maxr"
+kw208="dmed"
+kw209="dimm"
+kw210="drep"
+kw211="tmin"
+kw212="tmax"
+kw213="pmax"
+kw214="dmax"
+kw215="payt"
+kw216="fdp "
+kw217="fdsa"
+kw218="fdpa"
+kw219="extr"
+kw220="feci"
+kw221="rm2t"
+kw222="sm2t"
+kw223="tPAT"
+kw224="tPMT"
+kw225="tOD "
+kw226="tsti"
+kw227="istm"
+kw228="pm2t"
+kw229="rrtp"
+kw230="rssr"
+kw231="rscr"
+kw232="rsrp"
+kw233="rssr"
+kw234="ccid"
+kw235="sroc"
+kw236="prtp"
+kw237="roll"
+kw238="rash"
+kw239="alst"
+kw240="rap "
+kw241="tele"
+kw242="mp71"
+kw243="iso3"
+kw244="iso4"
+kw245="iso5"
+kw246="resv"
+kw247="iso6"