Remove libmedia and libstagefright dependency from extractors

- MediaSource, DataSource and MediaExtractor are moved to
  libmediaextractor so that they can be used by extractor
  implementations without depending on libmedia and libstagefright.
- XXXFactory classes has been added in order not to expose CreateXXX
  methods in libmediaextractor.
- avc_utils is moved to libstagefright_foundation since most of
  extractor implementations are relying on that.

Test: build + post submit media CTS tests
Bug: 65851881
Change-Id: I7d5cf18dd25abc10478ac3f6e7d1828ad023e3fb
diff --git a/media/libmediaextractor/Android.bp b/media/libmediaextractor/Android.bp
new file mode 100644
index 0000000..c57cd41
--- /dev/null
+++ b/media/libmediaextractor/Android.bp
@@ -0,0 +1,42 @@
+cc_library_shared {
+    name: "libmediaextractor",
+    include_dirs: [
+        "frameworks/av/include",
+        "frameworks/av/media/libmediaextractor/include",
+    ],
+
+    export_include_dirs: ["include"],
+
+    cflags: [
+        "-Wno-multichar",
+        "-Werror",
+        "-Wall",
+    ],
+
+    shared_libs: [
+        "libmediametrics",
+        "libstagefright_foundation",
+        "libutils",
+        "libcutils",
+        "liblog",
+    ],
+
+    srcs: [
+        "DataSource.cpp",
+        "MediaSource.cpp",
+        "MediaExtractor.cpp",
+    ],
+
+    clang: true,
+
+    sanitize: {
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+        cfi: true,
+        diag: {
+            cfi: true,
+        },
+    },
+}
diff --git a/media/libmediaextractor/DataSource.cpp b/media/libmediaextractor/DataSource.cpp
index e9aaa84..c22e4cb 100644
--- a/media/libmediaextractor/DataSource.cpp
+++ b/media/libmediaextractor/DataSource.cpp
@@ -16,28 +16,12 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "DataSource"
 
-#include "include/CallbackDataSource.h"
-#include "include/HTTPBase.h"
-#include "include/NuCachedSource2.h"
-
+#include <media/DataSource.h>
 #include <media/IDataSource.h>
-#include <media/IMediaHTTPConnection.h>
-#include <media/IMediaHTTPService.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/foundation/ByteUtils.h>
-#include <media/stagefright/DataSource.h>
-#include <media/stagefright/DataURISource.h>
-#include <media/stagefright/FileSource.h>
 #include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MediaHTTP.h>
-#include <media/stagefright/RemoteDataSource.h>
 #include <utils/String8.h>
 
-#include <cutils/properties.h>
-
-#include <private/android_filesystem_config.h>
-
 namespace android {
 
 bool DataSource::getUInt16(off64_t offset, uint16_t *x) {
@@ -144,103 +128,8 @@
     return nullptr;
 }
 
-////////////////////////////////////////////////////////////////////////////////
-
-// static
-sp<DataSource> DataSource::CreateFromURI(
-        const sp<IMediaHTTPService> &httpService,
-        const char *uri,
-        const KeyedVector<String8, String8> *headers,
-        String8 *contentType,
-        HTTPBase *httpSource) {
-    if (contentType != NULL) {
-        *contentType = "";
-    }
-
-    sp<DataSource> source;
-    if (!strncasecmp("file://", uri, 7)) {
-        source = new FileSource(uri + 7);
-    } else if (!strncasecmp("http://", uri, 7) || !strncasecmp("https://", uri, 8)) {
-        if (httpService == NULL) {
-            ALOGE("Invalid http service!");
-            return NULL;
-        }
-
-        if (httpSource == NULL) {
-            sp<IMediaHTTPConnection> conn = httpService->makeHTTPConnection();
-            if (conn == NULL) {
-                ALOGE("Failed to make http connection from http service!");
-                return NULL;
-            }
-            httpSource = new MediaHTTP(conn);
-        }
-
-        String8 cacheConfig;
-        bool disconnectAtHighwatermark = false;
-        KeyedVector<String8, String8> nonCacheSpecificHeaders;
-        if (headers != NULL) {
-            nonCacheSpecificHeaders = *headers;
-            NuCachedSource2::RemoveCacheSpecificHeaders(
-                    &nonCacheSpecificHeaders,
-                    &cacheConfig,
-                    &disconnectAtHighwatermark);
-        }
-
-        if (httpSource->connect(uri, &nonCacheSpecificHeaders) != OK) {
-            ALOGE("Failed to connect http source!");
-            return NULL;
-        }
-
-        if (contentType != NULL) {
-            *contentType = httpSource->getMIMEType();
-        }
-
-        source = NuCachedSource2::Create(
-                httpSource,
-                cacheConfig.isEmpty() ? NULL : cacheConfig.string(),
-                disconnectAtHighwatermark);
-    } else if (!strncasecmp("data:", uri, 5)) {
-        source = DataURISource::Create(uri);
-    } else {
-        // Assume it's a filename.
-        source = new FileSource(uri);
-    }
-
-    if (source == NULL || source->initCheck() != OK) {
-        return NULL;
-    }
-
-    return source;
-}
-
-sp<DataSource> DataSource::CreateFromFd(int fd, int64_t offset, int64_t length) {
-    sp<FileSource> source = new FileSource(fd, offset, length);
-    return source->initCheck() != OK ? nullptr : source;
-}
-
-sp<DataSource> DataSource::CreateMediaHTTP(const sp<IMediaHTTPService> &httpService) {
-    if (httpService == NULL) {
-        return NULL;
-    }
-
-    sp<IMediaHTTPConnection> conn = httpService->makeHTTPConnection();
-    if (conn == NULL) {
-        return NULL;
-    } else {
-        return new MediaHTTP(conn);
-    }
-}
-
-sp<DataSource> DataSource::CreateFromIDataSource(const sp<IDataSource> &source) {
-    return new TinyCacheSource(new CallbackDataSource(source));
-}
-
 String8 DataSource::getMIMEType() const {
     return String8("application/octet-stream");
 }
 
-sp<IDataSource> DataSource::asIDataSource() {
-    return RemoteDataSource::wrap(sp<DataSource>(this));
-}
-
 }  // namespace android
diff --git a/media/libmediaextractor/MediaExtractor.cpp b/media/libmediaextractor/MediaExtractor.cpp
index cc2fa63..6ba7c0e 100644
--- a/media/libmediaextractor/MediaExtractor.cpp
+++ b/media/libmediaextractor/MediaExtractor.cpp
@@ -17,42 +17,17 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "MediaExtractor"
 #include <utils/Log.h>
-#include <inttypes.h>
 #include <pwd.h>
 
-#include <binder/IServiceManager.h>
-#include <binder/MemoryDealer.h>
-
 #include <media/MediaAnalyticsItem.h>
+#include <media/MediaExtractor.h>
 #include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/DataSource.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaExtractor.h>
 #include <media/stagefright/MetaData.h>
-#include <media/stagefright/RemoteMediaExtractor.h>
-#include <media/IMediaExtractor.h>
-#include <media/IMediaExtractorService.h>
-#include <media/IMediaSource.h>
-#include <cutils/properties.h>
-#include <utils/String8.h>
-#include <private/android_filesystem_config.h>
-
-// still doing some on/off toggling here.
-#define MEDIA_LOG       1
-
-#include <sys/types.h>
-#include <dirent.h>
-#include <dlfcn.h>
 
 namespace android {
 
 // key for media statistics
 static const char *kKeyExtractor = "extractor";
-// attrs for media statistics
-static const char *kExtractorMime = "android.media.mediaextractor.mime";
-static const char *kExtractorTracks = "android.media.mediaextractor.ntrk";
-static const char *kExtractorFormat = "android.media.mediaextractor.fmt";
 
 MediaExtractor::MediaExtractor() {
     if (!LOG_NDEBUG) {
@@ -85,10 +60,6 @@
     }
 }
 
-sp<IMediaExtractor> MediaExtractor::asIMediaExtractor() {
-    return RemoteMediaExtractor::wrap(sp<MediaExtractor>(this));
-}
-
 sp<MetaData> MediaExtractor::getMetaData() {
     return new MetaData;
 }
@@ -114,213 +85,4 @@
     return CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_PAUSE | CAN_SEEK;
 }
 
-// static
-sp<IMediaExtractor> MediaExtractor::Create(
-        const sp<DataSource> &source, const char *mime) {
-    ALOGV("MediaExtractor::Create %s", mime);
-
-    if (!property_get_bool("media.stagefright.extractremote", true)) {
-        // local extractor
-        ALOGW("creating media extractor in calling process");
-        sp<MediaExtractor> extractor = CreateFromService(source, mime);
-        return (extractor.get() == nullptr) ? nullptr : extractor->asIMediaExtractor();
-    } else {
-        // remote extractor
-        ALOGV("get service manager");
-        sp<IBinder> binder = defaultServiceManager()->getService(String16("media.extractor"));
-
-        if (binder != 0) {
-            sp<IMediaExtractorService> mediaExService(interface_cast<IMediaExtractorService>(binder));
-            sp<IMediaExtractor> ex = mediaExService->makeExtractor(source->asIDataSource(), mime);
-            return ex;
-        } else {
-            ALOGE("extractor service not running");
-            return NULL;
-        }
-    }
-    return NULL;
-}
-
-sp<MediaExtractor> MediaExtractor::CreateFromService(
-        const sp<DataSource> &source, const char *mime) {
-
-    ALOGV("MediaExtractor::CreateFromService %s", mime);
-    RegisterDefaultSniffers();
-
-    // initialize source decryption if needed
-    source->DrmInitialization(nullptr /* mime */);
-
-    sp<AMessage> meta;
-
-    CreatorFunc creator = NULL;
-    String8 tmp;
-    float confidence;
-    creator = sniff(source, &tmp, &confidence, &meta);
-    if (!creator) {
-        ALOGV("FAILED to autodetect media content.");
-        return NULL;
-    }
-
-    mime = tmp.string();
-    ALOGV("Autodetected media content as '%s' with confidence %.2f",
-         mime, confidence);
-
-    MediaExtractor *ret = creator(source, meta);
-
-    if (ret != NULL) {
-        // track the container format (mpeg, aac, wvm, etc)
-        if (MEDIA_LOG) {
-            if (ret->mAnalyticsItem != NULL) {
-                size_t ntracks = ret->countTracks();
-                ret->mAnalyticsItem->setCString(kExtractorFormat,  ret->name());
-                // tracks (size_t)
-                ret->mAnalyticsItem->setInt32(kExtractorTracks,  ntracks);
-                // metadata
-                sp<MetaData> pMetaData = ret->getMetaData();
-                if (pMetaData != NULL) {
-                    String8 xx = pMetaData->toString();
-                    // 'titl' -- but this verges into PII
-                    // 'mime'
-                    const char *mime = NULL;
-                    if (pMetaData->findCString(kKeyMIMEType, &mime)) {
-                        ret->mAnalyticsItem->setCString(kExtractorMime,  mime);
-                    }
-                    // what else is interesting and not already available?
-                }
-            }
-        }
-    }
-
-    return ret;
-}
-
-Mutex MediaExtractor::gSnifferMutex;
-List<MediaExtractor::ExtractorDef> MediaExtractor::gSniffers;
-bool MediaExtractor::gSniffersRegistered = false;
-
-// static
-MediaExtractor::CreatorFunc MediaExtractor::sniff(
-        const sp<DataSource> &source, String8 *mimeType, float *confidence, sp<AMessage> *meta) {
-    *mimeType = "";
-    *confidence = 0.0f;
-    meta->clear();
-
-    {
-        Mutex::Autolock autoLock(gSnifferMutex);
-        if (!gSniffersRegistered) {
-            return NULL;
-        }
-    }
-
-    CreatorFunc curCreator = NULL;
-    CreatorFunc bestCreator = NULL;
-    for (List<ExtractorDef>::iterator it = gSniffers.begin();
-         it != gSniffers.end(); ++it) {
-        String8 newMimeType;
-        float newConfidence;
-        sp<AMessage> newMeta;
-        if ((curCreator = (*it).sniff(source, &newMimeType, &newConfidence, &newMeta))) {
-            if (newConfidence > *confidence) {
-                *mimeType = newMimeType;
-                *confidence = newConfidence;
-                *meta = newMeta;
-                bestCreator = curCreator;
-            }
-        }
-    }
-
-    return bestCreator;
-}
-
-// static
-void MediaExtractor::RegisterSniffer_l(const ExtractorDef &def) {
-    // sanity check check struct version, uuid, name
-    if (def.def_version == 0 || def.def_version > EXTRACTORDEF_VERSION) {
-        ALOGE("don't understand extractor format %u, ignoring.", def.def_version);
-        return;
-    }
-    if (memcmp(&def.extractor_uuid, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16) == 0) {
-        ALOGE("invalid UUID, ignoring");
-        return;
-    }
-    if (def.extractor_name == NULL || strlen(def.extractor_name) == 0) {
-        ALOGE("extractors should have a name, ignoring");
-        return;
-    }
-
-    for (List<ExtractorDef>::iterator it = gSniffers.begin();
-            it != gSniffers.end(); ++it) {
-        if (memcmp(&((*it).extractor_uuid), &def.extractor_uuid, 16) == 0) {
-            // there's already an extractor with the same uuid
-            if ((*it).extractor_version < def.extractor_version) {
-                // this one is newer, replace the old one
-                ALOGW("replacing extractor '%s' version %u with version %u",
-                        def.extractor_name,
-                        (*it).extractor_version,
-                        def.extractor_version);
-                gSniffers.erase(it);
-                break;
-            } else {
-                ALOGW("ignoring extractor '%s' version %u in favor of version %u",
-                        def.extractor_name,
-                        def.extractor_version,
-                        (*it).extractor_version);
-                return;
-            }
-        }
-    }
-    ALOGV("registering extractor for %s", def.extractor_name);
-    gSniffers.push_back(def);
-}
-
-// static
-void MediaExtractor::RegisterDefaultSniffers() {
-    Mutex::Autolock autoLock(gSnifferMutex);
-    if (gSniffersRegistered) {
-        return;
-    }
-
-    auto registerExtractors = [](const char *libDirPath) -> void {
-        DIR *libDir = opendir(libDirPath);
-        if (libDir) {
-            struct dirent* libEntry;
-            while ((libEntry = readdir(libDir))) {
-                String8 libPath = String8(libDirPath) + libEntry->d_name;
-                void *libHandle = dlopen(libPath.string(), RTLD_NOW | RTLD_LOCAL);
-                if (libHandle) {
-                    GetExtractorDef getsniffer = (GetExtractorDef) dlsym(libHandle, "GETEXTRACTORDEF");
-                    if (getsniffer) {
-                        ALOGV("registering sniffer for %s", libPath.string());
-                        RegisterSniffer_l(getsniffer());
-                    } else {
-                        ALOGW("%s does not contain sniffer", libPath.string());
-                        dlclose(libHandle);
-                    }
-                } else {
-                    ALOGW("couldn't dlopen(%s)", libPath.string());
-                }
-            }
-
-            closedir(libDir);
-        } else {
-            ALOGE("couldn't opendir(%s)", libDirPath);
-        }
-    };
-
-    registerExtractors("/system/lib"
-#ifdef __LP64__
-            "64"
-#endif
-            "/extractors/");
-
-    registerExtractors("/vendor/lib"
-#ifdef __LP64__
-            "64"
-#endif
-            "/extractors/");
-
-    gSniffersRegistered = true;
-}
-
-
 }  // namespace android
diff --git a/media/libmediaextractor/MediaSource.cpp b/media/libmediaextractor/MediaSource.cpp
index 8b92a6b..8038a59 100644
--- a/media/libmediaextractor/MediaSource.cpp
+++ b/media/libmediaextractor/MediaSource.cpp
@@ -14,9 +14,8 @@
  * limitations under the License.
  */
 
-#include <media/stagefright/CallbackMediaSource.h>
-#include <media/stagefright/MediaSource.h>
-#include <media/stagefright/RemoteMediaSource.h>
+#include <media/MediaSource.h>
+#include <media/IMediaSource.h>
 
 namespace android {
 
@@ -24,16 +23,56 @@
 
 MediaSource::~MediaSource() {}
 
-// static
-sp<MediaSource> MediaSource::CreateFromIMediaSource(const sp<IMediaSource> &source) {
-    if (source == nullptr) {
-        return nullptr;
-    }
-    return new CallbackMediaSource(source);
+////////////////////////////////////////////////////////////////////////////////
+
+MediaSource::ReadOptions::ReadOptions() {
+    reset();
 }
 
-sp<IMediaSource> MediaSource::asIMediaSource() {
-    return RemoteMediaSource::wrap(sp<MediaSource>(this));
+void MediaSource::ReadOptions::reset() {
+    mOptions = 0;
+    mSeekTimeUs = 0;
+    mLatenessUs = 0;
+    mNonBlocking = false;
+}
+
+void MediaSource::ReadOptions::setNonBlocking() {
+    mNonBlocking = true;
+}
+
+void MediaSource::ReadOptions::clearNonBlocking() {
+    mNonBlocking = false;
+}
+
+bool MediaSource::ReadOptions::getNonBlocking() const {
+    return mNonBlocking;
+}
+
+void MediaSource::ReadOptions::setSeekTo(int64_t time_us, SeekMode mode) {
+    mOptions |= kSeekTo_Option;
+    mSeekTimeUs = time_us;
+    mSeekMode = mode;
+}
+
+void MediaSource::ReadOptions::clearSeekTo() {
+    mOptions &= ~kSeekTo_Option;
+    mSeekTimeUs = 0;
+    mSeekMode = SEEK_CLOSEST_SYNC;
+}
+
+bool MediaSource::ReadOptions::getSeekTo(
+        int64_t *time_us, SeekMode *mode) const {
+    *time_us = mSeekTimeUs;
+    *mode = mSeekMode;
+    return (mOptions & kSeekTo_Option) != 0;
+}
+
+void MediaSource::ReadOptions::setLateBy(int64_t lateness_us) {
+    mLatenessUs = lateness_us;
+}
+
+int64_t MediaSource::ReadOptions::getLateBy() const {
+    return mLatenessUs;
 }
 
 }  // namespace android
diff --git a/media/libmediaextractor/include/media/DataSource.h b/media/libmediaextractor/include/media/DataSource.h
index bd863ba..e917f4e 100644
--- a/media/libmediaextractor/include/media/DataSource.h
+++ b/media/libmediaextractor/include/media/DataSource.h
@@ -47,17 +47,6 @@
         kIsLocalFileSource     = 16,
     };
 
-    static sp<DataSource> CreateFromURI(
-            const sp<IMediaHTTPService> &httpService,
-            const char *uri,
-            const KeyedVector<String8, String8> *headers = NULL,
-            String8 *contentType = NULL,
-            HTTPBase *httpSource = NULL);
-
-    static sp<DataSource> CreateMediaHTTP(const sp<IMediaHTTPService> &httpService);
-    static sp<DataSource> CreateFromIDataSource(const sp<IDataSource> &source);
-    static sp<DataSource> CreateFromFd(int fd, int64_t offset, int64_t length);
-
     DataSource() {}
 
     virtual status_t initCheck() const = 0;
@@ -123,9 +112,6 @@
 
     virtual void close() {};
 
-    // creates an IDataSource wrapper to the DataSource.
-    virtual sp<IDataSource> asIDataSource();
-
     // returns a pointer to IDataSource if it is wrapped.
     virtual sp<IDataSource> getIDataSource() const;
 
diff --git a/media/libmediaextractor/include/media/MediaExtractor.h b/media/libmediaextractor/include/media/MediaExtractor.h
index 441c6d7..2dcced3 100644
--- a/media/libmediaextractor/include/media/MediaExtractor.h
+++ b/media/libmediaextractor/include/media/MediaExtractor.h
@@ -19,23 +19,29 @@
 #define MEDIA_EXTRACTOR_H_
 
 #include <stdio.h>
+#include <vector>
 
-#include <media/IMediaExtractor.h>
-#include <media/MediaAnalyticsItem.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+// still doing some on/off toggling here.
+#define MEDIA_LOG       1
 
 namespace android {
 
 class DataSource;
-struct MediaSource;
+class IMediaSource;
+class MediaAnalyticsItem;
+class MediaExtractorFactory;
 class MetaData;
+class Parcel;
+class String8;
+struct AMessage;
+struct MediaSource;
+typedef std::vector<uint8_t> HInterfaceToken;
 
 class MediaExtractor : public RefBase {
 public:
-    static sp<IMediaExtractor> Create(
-            const sp<DataSource> &source, const char *mime = NULL);
-    static sp<MediaExtractor> CreateFromService(
-            const sp<DataSource> &source, const char *mime = NULL);
-
     virtual size_t countTracks() = 0;
     virtual sp<MediaSource> getTrack(size_t index) = 0;
 
@@ -62,9 +68,6 @@
     // CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK | CAN_PAUSE
     virtual uint32_t flags() const;
 
-    // Creates an IMediaExtractor wrapper to this MediaExtractor.
-    virtual sp<IMediaExtractor> asIMediaExtractor();
-
     // for DRM
     virtual char* getDrmTrackInfo(size_t /*trackID*/, int * /*len*/) {
         return NULL;
@@ -125,20 +128,9 @@
     virtual void populateMetrics();
 
 private:
-
-    static Mutex gSnifferMutex;
-    static List<ExtractorDef> gSniffers;
-    static bool gSniffersRegistered;
-
-    static void RegisterSniffer_l(const ExtractorDef &def);
-
-    static CreatorFunc sniff(const sp<DataSource> &source,
-            String8 *mimeType, float *confidence, sp<AMessage> *meta);
-
-    static void RegisterDefaultSniffers();
-
     MediaExtractor(const MediaExtractor &);
     MediaExtractor &operator=(const MediaExtractor &);
+    friend class MediaExtractorFactory;
 };
 
 // purposely not defined anywhere so that this will fail to link if
diff --git a/media/libmediaextractor/include/media/MediaSource.h b/media/libmediaextractor/include/media/MediaSource.h
index 7e30e30..749a4df 100644
--- a/media/libmediaextractor/include/media/MediaSource.h
+++ b/media/libmediaextractor/include/media/MediaSource.h
@@ -20,7 +20,8 @@
 
 #include <sys/types.h>
 
-#include <media/IMediaSource.h>
+#include <binder/IMemory.h>
+#include <binder/MemoryDealer.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
 #include <utils/RefBase.h>
@@ -33,15 +34,6 @@
 class IMediaSource;
 
 struct MediaSource : public virtual RefBase {
-    // TODO: Move ReadOptions implementation from IMediaSource to MediaSource
-    // once this class moves to a separate extractor lib on which both libmedia
-    // and libstagefright rely. For now, alias is added to avoid circular
-    // dependency.
-    using ReadOptions = IMediaSource::ReadOptions;
-
-    // Creates a MediaSource which wraps the given IMediaSource object.
-    static sp<MediaSource> CreateFromIMediaSource(const sp<IMediaSource> &source);
-
     MediaSource();
 
     // To be called before any other methods on this object, except
@@ -59,6 +51,51 @@
     // Returns the format of the data output by this media source.
     virtual sp<MetaData> getFormat() = 0;
 
+    // Options that modify read() behaviour. The default is to
+    // a) not request a seek
+    // b) not be late, i.e. lateness_us = 0
+    struct ReadOptions {
+        enum SeekMode : int32_t {
+            SEEK_PREVIOUS_SYNC,
+            SEEK_NEXT_SYNC,
+            SEEK_CLOSEST_SYNC,
+            SEEK_CLOSEST,
+        };
+
+        ReadOptions();
+
+        // Reset everything back to defaults.
+        void reset();
+
+        void setSeekTo(int64_t time_us, SeekMode mode = SEEK_CLOSEST_SYNC);
+        void clearSeekTo();
+        bool getSeekTo(int64_t *time_us, SeekMode *mode) const;
+
+        // TODO: remove this if unused.
+        void setLateBy(int64_t lateness_us);
+        int64_t getLateBy() const;
+
+        void setNonBlocking();
+        void clearNonBlocking();
+        bool getNonBlocking() const;
+
+        // Used to clear all non-persistent options for multiple buffer reads.
+        void clearNonPersistent() {
+            clearSeekTo();
+        }
+
+    private:
+        enum Options {
+            kSeekTo_Option      = 1,
+        };
+
+        uint32_t mOptions;
+        int64_t mSeekTimeUs;
+        SeekMode mSeekMode;
+        int64_t mLatenessUs;
+        bool mNonBlocking;
+    } __attribute__((packed)); // sent through Binder
+
     // Returns a new buffer of data. Call blocks until a
     // buffer is available, an error is encountered of the end of the stream
     // is reached.
@@ -103,9 +140,6 @@
         return ERROR_UNSUPPORTED;
     }
 
-    // Creates an IMediaSource wrapper to this MediaSource.
-    virtual sp<IMediaSource> asIMediaSource();
-
 protected:
     virtual ~MediaSource();