C-ify MediaTrack

Add C-API replacement for MediaTrack in extractor plugins.
Move MediaTrack from libmediaextractor.so to libmedia.so

Bug: 111407253
Test: CTS, manual

Change-Id: I3407e903fe41a2d7b7233538808281fce318c27a
diff --git a/include/media/MediaExtractorPluginApi.h b/include/media/MediaExtractorPluginApi.h
index 930b6e2..cccfc91 100644
--- a/include/media/MediaExtractorPluginApi.h
+++ b/include/media/MediaExtractorPluginApi.h
@@ -23,6 +23,7 @@
 
 struct MediaTrack;
 class MetaDataBase;
+class MediaBufferBase;
 
 extern "C" {
 
@@ -34,12 +35,33 @@
     void *handle;
 };
 
+enum CMediaTrackReadOptions : uint32_t {
+    SEEK_PREVIOUS_SYNC = 0,
+    SEEK_NEXT_SYNC = 1,
+    SEEK_CLOSEST_SYNC = 2,
+    SEEK_CLOSEST = 3,
+    SEEK_FRAME_INDEX = 4,
+    SEEK = 8,
+    NONBLOCKING = 16
+};
+
+struct CMediaTrack {
+    void *data;
+    void (*free)(void *data);
+
+    status_t (*start)(void *data, MetaDataBase *params);
+    status_t (*stop)(void *data);
+    status_t (*getFormat)(void *data, MetaDataBase &format);
+    status_t (*read)(void *data, MediaBufferBase **buffer, uint32_t options, int64_t seekPosUs);
+    bool     (*supportsNonBlockingRead)(void *data);
+};
+
 struct CMediaExtractor {
     void *data;
 
     void (*free)(void *data);
     size_t (*countTracks)(void *data);
-    MediaTrack* (*getTrack)(void *data, size_t index);
+    CMediaTrack* (*getTrack)(void *data, size_t index);
     status_t (*getTrackMetaData)(
             void *data,
             MetaDataBase& meta,
diff --git a/include/media/MediaExtractorPluginHelper.h b/include/media/MediaExtractorPluginHelper.h
index a659660..961033b 100644
--- a/include/media/MediaExtractorPluginHelper.h
+++ b/include/media/MediaExtractorPluginHelper.h
@@ -33,6 +33,75 @@
 class MetaDataBase;
 struct MediaTrack;
 
+
+class MediaTrackHelper {
+public:
+    virtual ~MediaTrackHelper() {};
+    virtual status_t start(MetaDataBase *params = NULL) = 0;
+    virtual status_t stop() = 0;
+    virtual status_t getFormat(MetaDataBase& format) = 0;
+
+    class ReadOptions {
+    public:
+        enum SeekMode : int32_t {
+            SEEK_PREVIOUS_SYNC,
+            SEEK_NEXT_SYNC,
+            SEEK_CLOSEST_SYNC,
+            SEEK_CLOSEST,
+            SEEK_FRAME_INDEX,
+        };
+
+        ReadOptions(uint32_t options, int64_t seekPosUs) {
+            mOptions = options;
+            mSeekPosUs = seekPosUs;
+        }
+        bool getSeekTo(int64_t *time_us, SeekMode *mode) const {
+            if ((mOptions & CMediaTrackReadOptions::SEEK) == 0) {
+                return false;
+            }
+            *time_us = mSeekPosUs;
+            *mode = (SeekMode) (mOptions & 7);
+            return true;
+        }
+        bool getNonBlocking() const {
+            return mOptions & CMediaTrackReadOptions::NONBLOCKING;
+        }
+    private:
+        uint32_t mOptions;
+        int64_t mSeekPosUs;
+    };
+
+    virtual status_t read(
+            MediaBufferBase **buffer, const ReadOptions *options = NULL) = 0;
+    virtual bool supportsNonBlockingRead() { return false; }
+};
+
+inline CMediaTrack *wrap(MediaTrackHelper *track) {
+    CMediaTrack *wrapper = (CMediaTrack*) malloc(sizeof(CMediaTrack));
+    wrapper->data = track;
+    wrapper->free = [](void *data) -> void {
+        delete (MediaTrackHelper*)(data);
+    };
+    wrapper->start = [](void *data, MetaDataBase *params) -> status_t {
+        return ((MediaTrackHelper*)data)->start(params);
+    };
+    wrapper->stop = [](void *data) -> status_t {
+        return ((MediaTrackHelper*)data)->stop();
+    };
+    wrapper->getFormat = [](void *data, MetaDataBase &meta) -> status_t {
+        return ((MediaTrackHelper*)data)->getFormat(meta);
+    };
+    wrapper->read = [](void *data, MediaBufferBase **buffer,  uint32_t options, int64_t seekPosUs)
+            -> status_t {
+        MediaTrackHelper::ReadOptions opts(options, seekPosUs);
+        return ((MediaTrackHelper*)data)->read(buffer, &opts);
+    };
+    wrapper->supportsNonBlockingRead = [](void *data) -> bool {
+                return ((MediaTrackHelper*)data)->supportsNonBlockingRead();
+    };
+    return wrapper;
+}
+
 // extractor plugins can derive from this class which looks remarkably
 // like MediaExtractor and can be easily wrapped in the required C API
 class MediaExtractorPluginHelper
@@ -40,7 +109,7 @@
 public:
     virtual ~MediaExtractorPluginHelper() {}
     virtual size_t countTracks() = 0;
-    virtual MediaTrack *getTrack(size_t index) = 0;
+    virtual MediaTrackHelper *getTrack(size_t index) = 0;
 
     enum GetTrackMetaDataFlags {
         kIncludeExtensiveMetaData = 1
@@ -89,8 +158,8 @@
     wrapper->countTracks = [](void *data) -> size_t {
         return ((MediaExtractorPluginHelper*)data)->countTracks();
     };
-    wrapper->getTrack = [](void *data, size_t index) -> MediaTrack* {
-        return ((MediaExtractorPluginHelper*)data)->getTrack(index);
+    wrapper->getTrack = [](void *data, size_t index) -> CMediaTrack* {
+        return wrap(((MediaExtractorPluginHelper*)data)->getTrack(index));
     };
     wrapper->getTrackMetaData = [](
             void *data,
diff --git a/include/media/MediaTrack.h b/include/media/MediaTrack.h
deleted file mode 120000
index 5a63287a..0000000
--- a/include/media/MediaTrack.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmediaextractor/include/media/MediaTrack.h
\ No newline at end of file
diff --git a/include/media/MediaTrack.h b/include/media/MediaTrack.h
new file mode 100644
index 0000000..3f77bda
--- /dev/null
+++ b/include/media/MediaTrack.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2018 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 MEDIA_SOURCE_BASE_H_
+
+#define MEDIA_SOURCE_BASE_H_
+
+#include <sys/types.h>
+
+#include <binder/IMemory.h>
+#include <binder/MemoryDealer.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MetaData.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <utils/Log.h>
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+class MediaBufferBase;
+struct CMediaTrack;
+
+class SourceBaseAllocTracker {
+public:
+    SourceBaseAllocTracker() {
+        ALOGD("sourcebase allocated: %p", this);
+    }
+    virtual ~SourceBaseAllocTracker() {
+        ALOGD("sourcebase freed: %p", this);
+    }
+};
+
+struct MediaTrack
+//    : public SourceBaseAllocTracker
+{
+    MediaTrack();
+
+    // To be called before any other methods on this object, except
+    // getFormat().
+    virtual status_t start(MetaDataBase *params = NULL) = 0;
+
+    // Any blocking read call returns immediately with a result of NO_INIT.
+    // It is an error to call any methods other than start after this call
+    // returns. Any buffers the object may be holding onto at the time of
+    // the stop() call are released.
+    // Also, it is imperative that any buffers output by this object and
+    // held onto by callers be released before a call to stop() !!!
+    virtual status_t stop() = 0;
+
+    // Returns the format of the data output by this media track.
+    virtual status_t getFormat(MetaDataBase& format) = 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 = CMediaTrackReadOptions::SEEK_PREVIOUS_SYNC,
+            SEEK_NEXT_SYNC = CMediaTrackReadOptions::SEEK_NEXT_SYNC,
+            SEEK_CLOSEST_SYNC = CMediaTrackReadOptions::SEEK_CLOSEST_SYNC,
+            SEEK_CLOSEST = CMediaTrackReadOptions::SEEK_CLOSEST,
+            SEEK_FRAME_INDEX = CMediaTrackReadOptions::SEEK_FRAME_INDEX,
+        };
+
+        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;
+
+        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;
+        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.
+    // End of stream is signalled by a result of ERROR_END_OF_STREAM.
+    // A result of INFO_FORMAT_CHANGED indicates that the format of this
+    // MediaSource has changed mid-stream, the client can continue reading
+    // but should be prepared for buffers of the new configuration.
+    virtual status_t read(
+            MediaBufferBase **buffer, const ReadOptions *options = NULL) = 0;
+
+    // Returns true if |read| supports nonblocking option, otherwise false.
+    // |readMultiple| if supported, always allows the nonblocking option.
+    virtual bool supportNonblockingRead() {
+        return false;
+    }
+
+    virtual ~MediaTrack();
+
+private:
+    MediaTrack(const MediaTrack &);
+    MediaTrack &operator=(const MediaTrack &);
+};
+
+class MediaTrackCUnwrapper : public MediaTrack {
+public:
+    explicit MediaTrackCUnwrapper(CMediaTrack *wrapper);
+
+    virtual status_t start(MetaDataBase *params = NULL);
+    virtual status_t stop();
+    virtual status_t getFormat(MetaDataBase& format);
+    virtual status_t read(MediaBufferBase **buffer, const ReadOptions *options = NULL);
+
+    virtual bool supportNonblockingRead();
+
+protected:
+    virtual ~MediaTrackCUnwrapper();
+
+private:
+    CMediaTrack *wrapper;
+};
+
+}  // namespace android
+
+#endif  // MEDIA_SOURCE_BASE_H_