Remove direct dependency on libbinder from extractor impls

This change removes dependency on IMediaExtractor/Source binder
interfaces from MediaExtractor implementations. Wrapper classes,
RemoteXXX and CallbackXXX, have been added to convert the
implementations to binder objects or the other way around.

Test: build, boot, and play mp4 video file
Bug: 65851881
Change-Id: I351fb7bbaf8e0154295ccf258f85b8b2f2a4b8fb
diff --git a/cmds/stagefright/audioloop.cpp b/cmds/stagefright/audioloop.cpp
index ed44b4d..67017eb 100644
--- a/cmds/stagefright/audioloop.cpp
+++ b/cmds/stagefright/audioloop.cpp
@@ -112,7 +112,7 @@
     looper->setName("audioloop");
     looper->start();
 
-    sp<IMediaSource> encoder = MediaCodecSource::Create(looper, meta, source);
+    sp<MediaSource> encoder = MediaCodecSource::Create(looper, meta, source);
 
     if (fileOut != NULL) {
         // target file specified, write encoded AMR output
@@ -128,7 +128,7 @@
         writer->stop();
     } else {
         // otherwise decode to speaker
-        sp<IMediaSource> decoder = SimpleDecodingSource::Create(encoder);
+        sp<MediaSource> decoder = SimpleDecodingSource::Create(encoder);
 
         if (playToSpeaker) {
             AudioPlayer *player = new AudioPlayer(NULL);
diff --git a/cmds/stagefright/record.cpp b/cmds/stagefright/record.cpp
index 94c2e96..69b00c9 100644
--- a/cmds/stagefright/record.cpp
+++ b/cmds/stagefright/record.cpp
@@ -320,7 +320,7 @@
     looper->setName("record");
     looper->start();
 
-    sp<IMediaSource> encoder =
+    sp<MediaSource> encoder =
         MediaCodecSource::Create(looper, encMeta, audioSource);
 
     encoder->start();
diff --git a/cmds/stagefright/recordvideo.cpp b/cmds/stagefright/recordvideo.cpp
index 7a3c842..af39d46 100644
--- a/cmds/stagefright/recordvideo.cpp
+++ b/cmds/stagefright/recordvideo.cpp
@@ -303,7 +303,7 @@
     looper->setName("recordvideo");
     looper->start();
 
-    sp<IMediaSource> encoder =
+    sp<MediaSource> encoder =
         MediaCodecSource::Create(
                 looper, enc_meta, source, NULL /* consumer */,
                 preferSoftwareCodec ? MediaCodecSource::FLAG_PREFER_SOFTWARE_CODEC : 0);
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index d70282b..7a5d129 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -141,7 +141,7 @@
     }
 }
 
-static void dumpSource(const sp<IMediaSource> &source, const String8 &filename) {
+static void dumpSource(const sp<MediaSource> &source, const String8 &filename) {
     FILE *out = fopen(filename.string(), "wb");
 
     CHECK_EQ((status_t)OK, source->start());
@@ -174,13 +174,13 @@
     out = NULL;
 }
 
-static void playSource(sp<IMediaSource> &source) {
+static void playSource(sp<MediaSource> &source) {
     sp<MetaData> meta = source->getFormat();
 
     const char *mime;
     CHECK(meta->findCString(kKeyMIMEType, &mime));
 
-    sp<IMediaSource> rawSource;
+    sp<MediaSource> rawSource;
     if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, mime)) {
         rawSource = source;
     } else {
@@ -404,7 +404,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 struct DetectSyncSource : public MediaSource {
-    explicit DetectSyncSource(const sp<IMediaSource> &source);
+    explicit DetectSyncSource(const sp<MediaSource> &source);
 
     virtual status_t start(MetaData *params = NULL);
     virtual status_t stop();
@@ -421,14 +421,14 @@
         OTHER,
     };
 
-    sp<IMediaSource> mSource;
+    sp<MediaSource> mSource;
     StreamType mStreamType;
     bool mSawFirstIDRFrame;
 
     DISALLOW_EVIL_CONSTRUCTORS(DetectSyncSource);
 };
 
-DetectSyncSource::DetectSyncSource(const sp<IMediaSource> &source)
+DetectSyncSource::DetectSyncSource(const sp<MediaSource> &source)
     : mSource(source),
       mStreamType(OTHER),
       mSawFirstIDRFrame(false) {
@@ -510,7 +510,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 static void writeSourcesToMP4(
-        Vector<sp<IMediaSource> > &sources, bool syncInfoPresent) {
+        Vector<sp<MediaSource> > &sources, bool syncInfoPresent) {
 #if 0
     sp<MPEG4Writer> writer =
         new MPEG4Writer(gWriteMP4Filename.string());
@@ -528,7 +528,7 @@
     writer->setMaxFileDuration(60000000ll);
 
     for (size_t i = 0; i < sources.size(); ++i) {
-        sp<IMediaSource> source = sources.editItemAt(i);
+        sp<MediaSource> source = sources.editItemAt(i);
 
         CHECK_EQ(writer->addSource(
                     syncInfoPresent ? source : new DetectSyncSource(source)),
@@ -545,7 +545,7 @@
     writer->stop();
 }
 
-static void performSeekTest(const sp<IMediaSource> &source) {
+static void performSeekTest(const sp<MediaSource> &source) {
     CHECK_EQ((status_t)OK, source->start());
 
     int64_t durationUs;
@@ -1002,8 +1002,8 @@
             isJPEG = true;
         }
 
-        Vector<sp<IMediaSource> > mediaSources;
-        sp<IMediaSource> mediaSource;
+        Vector<sp<MediaSource> > mediaSources;
+        sp<MediaSource> mediaSource;
 
         if (isJPEG) {
             mediaSource = new JPEGSource(dataSource);
@@ -1049,7 +1049,8 @@
                 bool haveAudio = false;
                 bool haveVideo = false;
                 for (size_t i = 0; i < numTracks; ++i) {
-                    sp<IMediaSource> source = extractor->getTrack(i);
+                    sp<MediaSource> source = MediaSource::CreateFromIMediaSource(
+                            extractor->getTrack(i));
                     if (source == nullptr) {
                         fprintf(stderr, "skip NULL track %zu, track count %zu.\n", i, numTracks);
                         continue;
@@ -1115,7 +1116,7 @@
                            thumbTimeUs, thumbTimeUs / 1E6);
                 }
 
-                mediaSource = extractor->getTrack(i);
+                mediaSource = MediaSource::CreateFromIMediaSource(extractor->getTrack(i));
                 if (mediaSource == nullptr) {
                     fprintf(stderr, "skip NULL track %zu, total tracks %zu.\n", i, numTracks);
                     return -1;
@@ -1128,7 +1129,7 @@
         } else if (dumpStream) {
             dumpSource(mediaSource, dumpStreamFilename);
         } else if (dumpPCMStream) {
-            sp<IMediaSource> decSource = SimpleDecodingSource::Create(mediaSource);
+            sp<MediaSource> decSource = SimpleDecodingSource::Create(mediaSource);
             dumpSource(decSource, dumpStreamFilename);
         } else if (seekTest) {
             performSeekTest(mediaSource);
diff --git a/cmds/stagefright/stream.cpp b/cmds/stagefright/stream.cpp
index 2e1d240..3b7a0e0 100644
--- a/cmds/stagefright/stream.cpp
+++ b/cmds/stagefright/stream.cpp
@@ -182,7 +182,7 @@
             continue;
         }
 
-        sp<IMediaSource> track = extractor->getTrack(i);
+        sp<MediaSource> track = MediaSource::CreateFromIMediaSource(extractor->getTrack(i));
         if (track == nullptr) {
             fprintf(stderr, "skip NULL track %zu, total tracks %zu\n", i, numTracks);
             continue;
diff --git a/media/libstagefright/AACExtractor.cpp b/media/libstagefright/AACExtractor.cpp
index 7449aa7..30fb5fe 100644
--- a/media/libstagefright/AACExtractor.cpp
+++ b/media/libstagefright/AACExtractor.cpp
@@ -213,7 +213,7 @@
     return mInitCheck == OK ? 1 : 0;
 }
 
-sp<IMediaSource> AACExtractor::getTrack(size_t index) {
+sp<MediaSource> AACExtractor::getTrack(size_t index) {
     if (mInitCheck != OK || index != 0) {
         return NULL;
     }
diff --git a/media/libstagefright/AACWriter.cpp b/media/libstagefright/AACWriter.cpp
index 8b1e1c3..9d90dbd 100644
--- a/media/libstagefright/AACWriter.cpp
+++ b/media/libstagefright/AACWriter.cpp
@@ -67,7 +67,7 @@
 }
 
 
-status_t AACWriter::addSource(const sp<IMediaSource> &source) {
+status_t AACWriter::addSource(const sp<MediaSource> &source) {
     if (mInitCheck != OK) {
         return mInitCheck;
     }
diff --git a/media/libstagefright/AMRExtractor.cpp b/media/libstagefright/AMRExtractor.cpp
index 2892520..8b4d14d 100644
--- a/media/libstagefright/AMRExtractor.cpp
+++ b/media/libstagefright/AMRExtractor.cpp
@@ -186,7 +186,7 @@
     return mInitCheck == OK ? 1 : 0;
 }
 
-sp<IMediaSource> AMRExtractor::getTrack(size_t index) {
+sp<MediaSource> AMRExtractor::getTrack(size_t index) {
     if (mInitCheck != OK || index != 0) {
         return NULL;
     }
diff --git a/media/libstagefright/AMRWriter.cpp b/media/libstagefright/AMRWriter.cpp
index 961b57f..f53d7f0 100644
--- a/media/libstagefright/AMRWriter.cpp
+++ b/media/libstagefright/AMRWriter.cpp
@@ -54,7 +54,7 @@
     return mInitCheck;
 }
 
-status_t AMRWriter::addSource(const sp<IMediaSource> &source) {
+status_t AMRWriter::addSource(const sp<MediaSource> &source) {
     if (mInitCheck != OK) {
         return mInitCheck;
     }
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 77a40c9..5481ae0 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -19,6 +19,7 @@
         "BufferImpl.cpp",
         "CodecBase.cpp",
         "CallbackDataSource.cpp",
+        "CallbackMediaSource.cpp",
         "CameraSource.cpp",
         "CameraSourceTimeLapse.cpp",
         "DataConverter.cpp",
@@ -53,6 +54,8 @@
         "OMXClient.cpp",
         "OmxInfoBuilder.cpp",
         "OggExtractor.cpp",
+        "RemoteMediaExtractor.cpp",
+        "RemoteMediaSource.cpp",
         "SampleIterator.cpp",
         "SampleTable.cpp",
         "SimpleDecodingSource.cpp",
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index b3fb8d4..1d441eb 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -67,7 +67,7 @@
     }
 }
 
-void AudioPlayer::setSource(const sp<IMediaSource> &source) {
+void AudioPlayer::setSource(const sp<MediaSource> &source) {
     CHECK(mSource == NULL);
     mSource = source;
 }
@@ -363,7 +363,7 @@
     // When offloading, the OMX component is not used so this hack
     // is not needed
     if (!useOffload()) {
-        wp<IMediaSource> tmp = mSource;
+        wp<MediaSource> tmp = mSource;
         mSource.clear();
         while (tmp.promote() != NULL) {
             usleep(1000);
diff --git a/media/libstagefright/CallbackMediaSource.cpp b/media/libstagefright/CallbackMediaSource.cpp
new file mode 100644
index 0000000..cc7147e
--- /dev/null
+++ b/media/libstagefright/CallbackMediaSource.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include <media/stagefright/CallbackMediaSource.h>
+
+namespace android {
+
+CallbackMediaSource::CallbackMediaSource(const sp<IMediaSource> &source)
+    :mSource(source) {}
+
+CallbackMediaSource::~CallbackMediaSource() {}
+
+status_t CallbackMediaSource::start(MetaData *params) {
+    return mSource->start(params);
+}
+
+status_t CallbackMediaSource::stop() {
+    return mSource->stop();
+}
+
+sp<MetaData> CallbackMediaSource::getFormat() {
+    return mSource->getFormat();
+}
+
+status_t CallbackMediaSource::read(MediaBuffer **buffer, const ReadOptions *options) {
+    return mSource->read(buffer, reinterpret_cast<const MediaSource::ReadOptions*>(options));
+}
+
+status_t CallbackMediaSource::pause() {
+    return mSource->pause();
+}
+
+status_t CallbackMediaSource::setBuffers(const Vector<MediaBuffer *> &buffers) {
+    return mSource->setBuffers(buffers);
+}
+
+}  // namespace android
diff --git a/media/libstagefright/FLACExtractor.cpp b/media/libstagefright/FLACExtractor.cpp
index 1b88e5d..99315d6 100644
--- a/media/libstagefright/FLACExtractor.cpp
+++ b/media/libstagefright/FLACExtractor.cpp
@@ -811,7 +811,7 @@
     return mInitCheck == OK ? 1 : 0;
 }
 
-sp<IMediaSource> FLACExtractor::getTrack(size_t index)
+sp<MediaSource> FLACExtractor::getTrack(size_t index)
 {
     if (mInitCheck != OK || index > 0) {
         return NULL;
diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index 22df522..2c696e5 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -407,7 +407,7 @@
     return mInitCheck != OK ? 0 : 1;
 }
 
-sp<IMediaSource> MP3Extractor::getTrack(size_t index) {
+sp<MediaSource> MP3Extractor::getTrack(size_t index) {
     if (mInitCheck != OK || index != 0) {
         return NULL;
     }
diff --git a/media/libstagefright/MPEG2TSWriter.cpp b/media/libstagefright/MPEG2TSWriter.cpp
index 03ea959..7ed8fce 100644
--- a/media/libstagefright/MPEG2TSWriter.cpp
+++ b/media/libstagefright/MPEG2TSWriter.cpp
@@ -35,7 +35,7 @@
 namespace android {
 
 struct MPEG2TSWriter::SourceInfo : public AHandler {
-    explicit SourceInfo(const sp<IMediaSource> &source);
+    explicit SourceInfo(const sp<MediaSource> &source);
 
     void start(const sp<AMessage> &notify, const sp<MetaData> &params);
     void stop();
@@ -69,7 +69,7 @@
         kWhatRead  = 'read',
     };
 
-    sp<IMediaSource> mSource;
+    sp<MediaSource> mSource;
     sp<ALooper> mLooper;
     sp<AMessage> mNotify;
 
@@ -91,7 +91,7 @@
     DISALLOW_EVIL_CONSTRUCTORS(SourceInfo);
 };
 
-MPEG2TSWriter::SourceInfo::SourceInfo(const sp<IMediaSource> &source)
+MPEG2TSWriter::SourceInfo::SourceInfo(const sp<MediaSource> &source)
     : mSource(source),
       mLooper(new ALooper),
       mEOSReceived(false),
@@ -499,7 +499,7 @@
     }
 }
 
-status_t MPEG2TSWriter::addSource(const sp<IMediaSource> &source) {
+status_t MPEG2TSWriter::addSource(const sp<MediaSource> &source) {
     CHECK(!mStarted);
 
     sp<MetaData> meta = source->getFormat();
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index f112b10..e130b4a 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -3344,7 +3344,7 @@
     }
 }
 
-sp<IMediaSource> MPEG4Extractor::getTrack(size_t index) {
+sp<MediaSource> MPEG4Extractor::getTrack(size_t index) {
     status_t err;
     if ((err = readMetaData()) != OK) {
         return NULL;
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 7786c4d..8c121b3 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -100,7 +100,7 @@
 
 class MPEG4Writer::Track {
 public:
-    Track(MPEG4Writer *owner, const sp<IMediaSource> &source, size_t trackId);
+    Track(MPEG4Writer *owner, const sp<MediaSource> &source, size_t trackId);
 
     ~Track();
 
@@ -271,7 +271,7 @@
 
     MPEG4Writer *mOwner;
     sp<MetaData> mMeta;
-    sp<IMediaSource> mSource;
+    sp<MediaSource> mSource;
     volatile bool mDone;
     volatile bool mPaused;
     volatile bool mResumed;
@@ -572,7 +572,7 @@
     return NULL;
 }
 
-status_t MPEG4Writer::addSource(const sp<IMediaSource> &source) {
+status_t MPEG4Writer::addSource(const sp<MediaSource> &source) {
     Mutex::Autolock l(mLock);
     if (mStarted) {
         ALOGE("Attempt to add source AFTER recording is started");
@@ -1626,7 +1626,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 MPEG4Writer::Track::Track(
-        MPEG4Writer *owner, const sp<IMediaSource> &source, size_t trackId)
+        MPEG4Writer *owner, const sp<MediaSource> &source, size_t trackId)
     : mOwner(owner),
       mMeta(source->getFormat()),
       mSource(source),
diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp
index 26b8fd3..14e6251 100644
--- a/media/libstagefright/MediaExtractor.cpp
+++ b/media/libstagefright/MediaExtractor.cpp
@@ -43,7 +43,10 @@
 #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>
@@ -92,6 +95,10 @@
     }
 }
 
+sp<IMediaExtractor> MediaExtractor::asIMediaExtractor() {
+    return RemoteMediaExtractor::wrap(sp<MediaExtractor>(this));
+}
+
 sp<MetaData> MediaExtractor::getMetaData() {
     return new MetaData;
 }
@@ -125,7 +132,8 @@
     if (!property_get_bool("media.stagefright.extractremote", true)) {
         // local extractor
         ALOGW("creating media extractor in calling process");
-        return CreateFromService(source, mime);
+        sp<MediaExtractor> extractor = CreateFromService(source, mime);
+        return (extractor.get() == nullptr) ? nullptr : extractor->asIMediaExtractor();
     } else {
         // remote extractor
         ALOGV("get service manager");
diff --git a/media/libstagefright/MediaSource.cpp b/media/libstagefright/MediaSource.cpp
index a17757a..8b92a6b 100644
--- a/media/libstagefright/MediaSource.cpp
+++ b/media/libstagefright/MediaSource.cpp
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 
+#include <media/stagefright/CallbackMediaSource.h>
 #include <media/stagefright/MediaSource.h>
+#include <media/stagefright/RemoteMediaSource.h>
 
 namespace android {
 
@@ -22,4 +24,16 @@
 
 MediaSource::~MediaSource() {}
 
+// static
+sp<MediaSource> MediaSource::CreateFromIMediaSource(const sp<IMediaSource> &source) {
+    if (source == nullptr) {
+        return nullptr;
+    }
+    return new CallbackMediaSource(source);
+}
+
+sp<IMediaSource> MediaSource::asIMediaSource() {
+    return RemoteMediaSource::wrap(sp<MediaSource>(this));
+}
+
 }  // namespace android
diff --git a/media/libstagefright/MidiExtractor.cpp b/media/libstagefright/MidiExtractor.cpp
index 7930bbb..89cfa3c 100644
--- a/media/libstagefright/MidiExtractor.cpp
+++ b/media/libstagefright/MidiExtractor.cpp
@@ -282,7 +282,7 @@
     return mInitCheck == OK ? 1 : 0;
 }
 
-sp<IMediaSource> MidiExtractor::getTrack(size_t index)
+sp<MediaSource> MidiExtractor::getTrack(size_t index)
 {
     if (mInitCheck != OK || index > 0) {
         return NULL;
diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp
index 810b0d6..0e09ccb 100644
--- a/media/libstagefright/OggExtractor.cpp
+++ b/media/libstagefright/OggExtractor.cpp
@@ -1344,7 +1344,7 @@
     return mInitCheck != OK ? 0 : 1;
 }
 
-sp<IMediaSource> OggExtractor::getTrack(size_t index) {
+sp<MediaSource> OggExtractor::getTrack(size_t index) {
     if (index >= 1) {
         return NULL;
     }
diff --git a/media/libstagefright/RemoteMediaExtractor.cpp b/media/libstagefright/RemoteMediaExtractor.cpp
new file mode 100644
index 0000000..db2c20c
--- /dev/null
+++ b/media/libstagefright/RemoteMediaExtractor.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include <media/stagefright/RemoteMediaExtractor.h>
+#include <media/stagefright/MediaSource.h>
+
+namespace android {
+
+RemoteMediaExtractor::RemoteMediaExtractor(const sp<MediaExtractor> &extractor)
+    :mExtractor(extractor) {}
+
+RemoteMediaExtractor::~RemoteMediaExtractor() {}
+
+size_t RemoteMediaExtractor::countTracks() {
+    return mExtractor->countTracks();
+}
+
+sp<IMediaSource> RemoteMediaExtractor::getTrack(size_t index) {
+    sp<MediaSource> source = mExtractor->getTrack(index);
+    return (source.get() == nullptr) ? nullptr : source->asIMediaSource();
+}
+
+sp<MetaData> RemoteMediaExtractor::getTrackMetaData(size_t index, uint32_t flags) {
+    return mExtractor->getTrackMetaData(index, flags);
+}
+
+sp<MetaData> RemoteMediaExtractor::getMetaData() {
+    return mExtractor->getMetaData();
+}
+
+status_t RemoteMediaExtractor::getMetrics(Parcel *reply) {
+    return mExtractor->getMetrics(reply);
+}
+
+uint32_t RemoteMediaExtractor::flags() const {
+    return mExtractor->flags();
+}
+
+char* RemoteMediaExtractor::getDrmTrackInfo(size_t trackID, int * len) {
+    return mExtractor->getDrmTrackInfo(trackID, len);
+}
+
+void RemoteMediaExtractor::setUID(uid_t uid) {
+    return mExtractor->setUID(uid);
+}
+
+status_t RemoteMediaExtractor::setMediaCas(const HInterfaceToken &casToken) {
+    return mExtractor->setMediaCas(casToken);
+}
+
+const char * RemoteMediaExtractor::name() {
+    return mExtractor->name();
+}
+
+void RemoteMediaExtractor::release() {
+    return mExtractor->release();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+// static
+sp<IMediaExtractor> RemoteMediaExtractor::wrap(const sp<MediaExtractor> &extractor) {
+    if (extractor.get() == nullptr) {
+        return nullptr;
+    }
+    return new RemoteMediaExtractor(extractor);
+}
+
+}  // namespace android
diff --git a/media/libstagefright/RemoteMediaSource.cpp b/media/libstagefright/RemoteMediaSource.cpp
new file mode 100644
index 0000000..4060526
--- /dev/null
+++ b/media/libstagefright/RemoteMediaSource.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+#include <media/stagefright/RemoteMediaSource.h>
+
+namespace android {
+
+RemoteMediaSource::RemoteMediaSource(const sp<MediaSource> &source)
+    :mSource(source) {}
+
+RemoteMediaSource::~RemoteMediaSource() {}
+
+status_t RemoteMediaSource::start(MetaData *params) {
+    return mSource->start(params);
+}
+
+status_t RemoteMediaSource::stop() {
+    return mSource->stop();
+}
+
+sp<MetaData> RemoteMediaSource::getFormat() {
+    return mSource->getFormat();
+}
+
+status_t RemoteMediaSource::read(MediaBuffer **buffer, const ReadOptions *options) {
+    return mSource->read(buffer, reinterpret_cast<const MediaSource::ReadOptions*>(options));
+}
+
+status_t RemoteMediaSource::pause() {
+    return mSource->pause();
+}
+
+status_t RemoteMediaSource::setBuffers(const Vector<MediaBuffer *> &buffers) {
+    return mSource->setBuffers(buffers);
+}
+
+status_t RemoteMediaSource::setStopTimeUs(int64_t stopTimeUs) {
+    return mSource->setStopTimeUs(stopTimeUs);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+// static
+sp<IMediaSource> RemoteMediaSource::wrap(const sp<MediaSource> &source) {
+    if (source.get() == nullptr) {
+        return nullptr;
+    }
+    return new RemoteMediaSource(source);
+}
+
+}  // namespace android
diff --git a/media/libstagefright/SimpleDecodingSource.cpp b/media/libstagefright/SimpleDecodingSource.cpp
index 90b8603..67e6748 100644
--- a/media/libstagefright/SimpleDecodingSource.cpp
+++ b/media/libstagefright/SimpleDecodingSource.cpp
@@ -36,13 +36,13 @@
 
 //static
 sp<SimpleDecodingSource> SimpleDecodingSource::Create(
-        const sp<IMediaSource> &source, uint32_t flags) {
+        const sp<MediaSource> &source, uint32_t flags) {
     return SimpleDecodingSource::Create(source, flags, nullptr, nullptr);
 }
 
 //static
 sp<SimpleDecodingSource> SimpleDecodingSource::Create(
-        const sp<IMediaSource> &source, uint32_t flags, const sp<ANativeWindow> &nativeWindow,
+        const sp<MediaSource> &source, uint32_t flags, const sp<ANativeWindow> &nativeWindow,
         const char *desiredCodec) {
     sp<Surface> surface = static_cast<Surface*>(nativeWindow.get());
     const char *mime = NULL;
@@ -99,7 +99,7 @@
 }
 
 SimpleDecodingSource::SimpleDecodingSource(
-        const sp<MediaCodec> &codec, const sp<IMediaSource> &source, const sp<ALooper> &looper,
+        const sp<MediaCodec> &codec, const sp<MediaSource> &source, const sp<ALooper> &looper,
         bool usingSurface, bool isVorbis, const sp<AMessage> &format)
     : mCodec(codec),
       mSource(source),
@@ -212,7 +212,7 @@
     status_t res;
 
     // flush codec on seek
-    IMediaSource::ReadOptions::SeekMode mode;
+    MediaSource::ReadOptions::SeekMode mode;
     if (options != NULL && options->getSeekTo(&out_pts, &mode)) {
         me->mQueuedInputEOS = false;
         me->mGotOutputEOS = false;
diff --git a/media/libstagefright/WAVExtractor.cpp b/media/libstagefright/WAVExtractor.cpp
index 780b746..18bf4ae 100644
--- a/media/libstagefright/WAVExtractor.cpp
+++ b/media/libstagefright/WAVExtractor.cpp
@@ -120,7 +120,7 @@
     return mInitCheck == OK ? 1 : 0;
 }
 
-sp<IMediaSource> WAVExtractor::getTrack(size_t index) {
+sp<MediaSource> WAVExtractor::getTrack(size_t index) {
     if (mInitCheck != OK || index > 0) {
         return NULL;
     }
diff --git a/media/libstagefright/include/AACExtractor.h b/media/libstagefright/include/AACExtractor.h
index bd4c41c..91e2eed 100644
--- a/media/libstagefright/include/AACExtractor.h
+++ b/media/libstagefright/include/AACExtractor.h
@@ -32,7 +32,7 @@
     AACExtractor(const sp<DataSource> &source, const sp<AMessage> &meta);
 
     virtual size_t countTracks();
-    virtual sp<IMediaSource> getTrack(size_t index);
+    virtual sp<MediaSource> getTrack(size_t index);
     virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
 
     virtual sp<MetaData> getMetaData();
diff --git a/media/libstagefright/include/AMRExtractor.h b/media/libstagefright/include/AMRExtractor.h
index 8abcb12..06cd387 100644
--- a/media/libstagefright/include/AMRExtractor.h
+++ b/media/libstagefright/include/AMRExtractor.h
@@ -32,7 +32,7 @@
     explicit AMRExtractor(const sp<DataSource> &source);
 
     virtual size_t countTracks();
-    virtual sp<IMediaSource> getTrack(size_t index);
+    virtual sp<MediaSource> getTrack(size_t index);
     virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
 
     virtual sp<MetaData> getMetaData();
diff --git a/media/libstagefright/include/FLACExtractor.h b/media/libstagefright/include/FLACExtractor.h
index 51bc139..e945cf6 100644
--- a/media/libstagefright/include/FLACExtractor.h
+++ b/media/libstagefright/include/FLACExtractor.h
@@ -32,7 +32,7 @@
     explicit FLACExtractor(const sp<DataSource> &source);
 
     virtual size_t countTracks();
-    virtual sp<IMediaSource> getTrack(size_t index);
+    virtual sp<MediaSource> getTrack(size_t index);
     virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
 
     virtual sp<MetaData> getMetaData();
diff --git a/media/libstagefright/include/MP3Extractor.h b/media/libstagefright/include/MP3Extractor.h
index 2fd04f2..2b16c24 100644
--- a/media/libstagefright/include/MP3Extractor.h
+++ b/media/libstagefright/include/MP3Extractor.h
@@ -34,7 +34,7 @@
     MP3Extractor(const sp<DataSource> &source, const sp<AMessage> &meta);
 
     virtual size_t countTracks();
-    virtual sp<IMediaSource> getTrack(size_t index);
+    virtual sp<MediaSource> getTrack(size_t index);
     virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
 
     virtual sp<MetaData> getMetaData();
diff --git a/media/libstagefright/include/MPEG2PSExtractor.h b/media/libstagefright/include/MPEG2PSExtractor.h
index f5471b3..75e1346 100644
--- a/media/libstagefright/include/MPEG2PSExtractor.h
+++ b/media/libstagefright/include/MPEG2PSExtractor.h
@@ -34,7 +34,7 @@
     explicit MPEG2PSExtractor(const sp<DataSource> &source);
 
     virtual size_t countTracks();
-    virtual sp<IMediaSource> getTrack(size_t index);
+    virtual sp<MediaSource> getTrack(size_t index);
     virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
 
     virtual sp<MetaData> getMetaData();
diff --git a/media/libstagefright/include/MPEG2TSExtractor.h b/media/libstagefright/include/MPEG2TSExtractor.h
index ac93b5e..1702157 100644
--- a/media/libstagefright/include/MPEG2TSExtractor.h
+++ b/media/libstagefright/include/MPEG2TSExtractor.h
@@ -40,7 +40,7 @@
     explicit MPEG2TSExtractor(const sp<DataSource> &source);
 
     virtual size_t countTracks();
-    virtual sp<IMediaSource> getTrack(size_t index);
+    virtual sp<MediaSource> getTrack(size_t index);
     virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
 
     virtual sp<MetaData> getMetaData();
diff --git a/media/libstagefright/include/MPEG4Extractor.h b/media/libstagefright/include/MPEG4Extractor.h
index 214a3de..bd404d2 100644
--- a/media/libstagefright/include/MPEG4Extractor.h
+++ b/media/libstagefright/include/MPEG4Extractor.h
@@ -56,7 +56,7 @@
     explicit MPEG4Extractor(const sp<DataSource> &source);
 
     virtual size_t countTracks();
-    virtual sp<IMediaSource> getTrack(size_t index);
+    virtual sp<MediaSource> getTrack(size_t index);
     virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
 
     virtual sp<MetaData> getMetaData();
diff --git a/media/libstagefright/include/MidiExtractor.h b/media/libstagefright/include/MidiExtractor.h
index 94d2d08..87a4a02 100644
--- a/media/libstagefright/include/MidiExtractor.h
+++ b/media/libstagefright/include/MidiExtractor.h
@@ -56,7 +56,7 @@
     explicit MidiExtractor(const sp<DataSource> &source);
 
     virtual size_t countTracks();
-    virtual sp<IMediaSource> getTrack(size_t index);
+    virtual sp<MediaSource> getTrack(size_t index);
     virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
 
     virtual sp<MetaData> getMetaData();
diff --git a/media/libstagefright/include/OggExtractor.h b/media/libstagefright/include/OggExtractor.h
index 55aafed..c01850f 100644
--- a/media/libstagefright/include/OggExtractor.h
+++ b/media/libstagefright/include/OggExtractor.h
@@ -34,7 +34,7 @@
     explicit OggExtractor(const sp<DataSource> &source);
 
     virtual size_t countTracks();
-    virtual sp<IMediaSource> getTrack(size_t index);
+    virtual sp<MediaSource> getTrack(size_t index);
     virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
 
     virtual sp<MetaData> getMetaData();
diff --git a/media/libstagefright/include/WAVExtractor.h b/media/libstagefright/include/WAVExtractor.h
index 12ad441..dbcbe86 100644
--- a/media/libstagefright/include/WAVExtractor.h
+++ b/media/libstagefright/include/WAVExtractor.h
@@ -33,7 +33,7 @@
     explicit WAVExtractor(const sp<DataSource> &source);
 
     virtual size_t countTracks();
-    virtual sp<IMediaSource> getTrack(size_t index);
+    virtual sp<MediaSource> getTrack(size_t index);
     virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
 
     virtual sp<MetaData> getMetaData();
diff --git a/media/libstagefright/include/media/stagefright/AACWriter.h b/media/libstagefright/include/media/stagefright/AACWriter.h
index a1f63d7..aa60a19 100644
--- a/media/libstagefright/include/media/stagefright/AACWriter.h
+++ b/media/libstagefright/include/media/stagefright/AACWriter.h
@@ -31,7 +31,7 @@
 
     status_t initCheck() const;
 
-    virtual status_t addSource(const sp<IMediaSource> &source);
+    virtual status_t addSource(const sp<MediaSource> &source);
     virtual bool reachedEOS();
     virtual status_t start(MetaData *params = NULL);
     virtual status_t stop() { return reset(); }
@@ -48,7 +48,7 @@
 
     int   mFd;
     status_t mInitCheck;
-    sp<IMediaSource> mSource;
+    sp<MediaSource> mSource;
     bool mStarted;
     volatile bool mPaused;
     volatile bool mResumed;
diff --git a/media/libstagefright/include/media/stagefright/AMRWriter.h b/media/libstagefright/include/media/stagefright/AMRWriter.h
index fbbdf2e..7d2c879 100644
--- a/media/libstagefright/include/media/stagefright/AMRWriter.h
+++ b/media/libstagefright/include/media/stagefright/AMRWriter.h
@@ -20,7 +20,6 @@
 
 #include <stdio.h>
 
-#include <media/IMediaSource.h>
 #include <media/stagefright/MediaWriter.h>
 #include <utils/threads.h>
 
@@ -33,7 +32,7 @@
 
     status_t initCheck() const;
 
-    virtual status_t addSource(const sp<IMediaSource> &source);
+    virtual status_t addSource(const sp<MediaSource> &source);
     virtual bool reachedEOS();
     virtual status_t start(MetaData *params = NULL);
     virtual status_t stop() { return reset(); }
@@ -45,7 +44,7 @@
 private:
     int   mFd;
     status_t mInitCheck;
-    sp<IMediaSource> mSource;
+    sp<MediaSource> mSource;
     bool mStarted;
     volatile bool mPaused;
     volatile bool mResumed;
diff --git a/media/libstagefright/include/media/stagefright/AudioPlayer.h b/media/libstagefright/include/media/stagefright/AudioPlayer.h
index f7499b6..581ead9 100644
--- a/media/libstagefright/include/media/stagefright/AudioPlayer.h
+++ b/media/libstagefright/include/media/stagefright/AudioPlayer.h
@@ -18,9 +18,9 @@
 
 #define AUDIO_PLAYER_H_
 
-#include <media/IMediaSource.h>
 #include <media/MediaPlayerInterface.h>
 #include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaSource.h>
 #include <utils/threads.h>
 
 namespace android {
@@ -50,7 +50,7 @@
     virtual ~AudioPlayer();
 
     // Caller retains ownership of "source".
-    void setSource(const sp<IMediaSource> &source);
+    void setSource(const sp<MediaSource> &source);
 
     status_t start(bool sourceAlreadyStarted = false);
 
@@ -66,7 +66,7 @@
     status_t getPlaybackRate(AudioPlaybackRate *rate /* nonnull */);
 
 private:
-    sp<IMediaSource> mSource;
+    sp<MediaSource> mSource;
     sp<AudioTrack> mAudioTrack;
 
     MediaBuffer *mInputBuffer;
diff --git a/media/libstagefright/include/media/stagefright/CallbackMediaSource.h b/media/libstagefright/include/media/stagefright/CallbackMediaSource.h
new file mode 100644
index 0000000..17fca4e
--- /dev/null
+++ b/media/libstagefright/include/media/stagefright/CallbackMediaSource.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2017, 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 CALLBACK_MEDIA_SOURCE_H_
+#define CALLBACK_MEDIA_SOURCE_H_
+
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/foundation/ABase.h>
+
+namespace android {
+
+// A stagefright MediaSource that wraps a binder IMediaSource.
+class CallbackMediaSource : public MediaSource {
+public:
+    explicit CallbackMediaSource(const sp<IMediaSource> &source);
+    virtual ~CallbackMediaSource();
+    virtual status_t start(MetaData *params = NULL);
+    virtual status_t stop();
+    virtual sp<MetaData> getFormat();
+    virtual status_t read(
+            MediaBuffer **buffer, const ReadOptions *options = NULL);
+    virtual status_t pause();
+    virtual status_t setBuffers(const Vector<MediaBuffer *> &buffers);
+
+private:
+    sp<IMediaSource> mSource;
+
+    DISALLOW_EVIL_CONSTRUCTORS(CallbackMediaSource);
+};
+
+}  // namespace android
+
+#endif  // CALLBACK_MEDIA_SOURCE_H_
diff --git a/media/libstagefright/include/media/stagefright/MPEG2TSWriter.h b/media/libstagefright/include/media/stagefright/MPEG2TSWriter.h
index 4516fb6..3d7960b 100644
--- a/media/libstagefright/include/media/stagefright/MPEG2TSWriter.h
+++ b/media/libstagefright/include/media/stagefright/MPEG2TSWriter.h
@@ -34,7 +34,7 @@
             void *cookie,
             ssize_t (*write)(void *cookie, const void *data, size_t size));
 
-    virtual status_t addSource(const sp<IMediaSource> &source);
+    virtual status_t addSource(const sp<MediaSource> &source);
     virtual status_t start(MetaData *param = NULL);
     virtual status_t stop() { return reset(); }
     virtual status_t pause();
diff --git a/media/libstagefright/include/media/stagefright/MPEG4Writer.h b/media/libstagefright/include/media/stagefright/MPEG4Writer.h
index 1c7b4a6..eba3b32 100644
--- a/media/libstagefright/include/media/stagefright/MPEG4Writer.h
+++ b/media/libstagefright/include/media/stagefright/MPEG4Writer.h
@@ -20,7 +20,6 @@
 
 #include <stdio.h>
 
-#include <media/IMediaSource.h>
 #include <media/stagefright/MediaWriter.h>
 #include <utils/List.h>
 #include <utils/threads.h>
@@ -40,7 +39,7 @@
     // Limitations
     // No more than one video and/or one audio source can be added, but
     // multiple metadata sources can be added.
-    virtual status_t addSource(const sp<IMediaSource> &source);
+    virtual status_t addSource(const sp<MediaSource> &source);
 
     // Returns INVALID_OPERATION if there is no source or track.
     virtual status_t start(MetaData *param = NULL);
diff --git a/media/libstagefright/include/media/stagefright/MediaExtractor.h b/media/libstagefright/include/media/stagefright/MediaExtractor.h
index 6ec7eaf..f8eb7fd 100644
--- a/media/libstagefright/include/media/stagefright/MediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/MediaExtractor.h
@@ -19,15 +19,15 @@
 #define MEDIA_EXTRACTOR_H_
 
 #include <media/IMediaExtractor.h>
-#include <media/IMediaSource.h>
 #include <media/MediaAnalyticsItem.h>
 
 namespace android {
+
 class DataSource;
 struct MediaSource;
 class MetaData;
 
-class MediaExtractor : public BnMediaExtractor {
+class MediaExtractor : public RefBase {
 public:
     static sp<IMediaExtractor> Create(
             const sp<DataSource> &source, const char *mime = NULL);
@@ -35,7 +35,7 @@
             const sp<DataSource> &source, const char *mime = NULL);
 
     virtual size_t countTracks() = 0;
-    virtual sp<IMediaSource> getTrack(size_t index) = 0;
+    virtual sp<MediaSource> getTrack(size_t index) = 0;
 
     enum GetTrackMetaDataFlags {
         kIncludeExtensiveMetaData = 1
@@ -60,13 +60,16 @@
     // 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;
     }
     virtual void setUID(uid_t /*uid*/) {
     }
-    virtual status_t setMediaCas(const HInterfaceToken &/*casToken*/) override {
+    virtual status_t setMediaCas(const HInterfaceToken &/*casToken*/) {
         return INVALID_OPERATION;
     }
 
diff --git a/media/libstagefright/include/media/stagefright/MediaSource.h b/media/libstagefright/include/media/stagefright/MediaSource.h
index 14adb05..7e30e30 100644
--- a/media/libstagefright/include/media/stagefright/MediaSource.h
+++ b/media/libstagefright/include/media/stagefright/MediaSource.h
@@ -22,6 +22,7 @@
 
 #include <media/IMediaSource.h>
 #include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MetaData.h>
 #include <utils/RefBase.h>
 #include <utils/Vector.h>
 
@@ -29,8 +30,18 @@
 
 class MediaBuffer;
 class MetaData;
+class IMediaSource;
 
-struct MediaSource : public BnMediaSource {
+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
@@ -92,6 +103,9 @@
         return ERROR_UNSUPPORTED;
     }
 
+    // Creates an IMediaSource wrapper to this MediaSource.
+    virtual sp<IMediaSource> asIMediaSource();
+
 protected:
     virtual ~MediaSource();
 
diff --git a/media/libstagefright/include/media/stagefright/MediaWriter.h b/media/libstagefright/include/media/stagefright/MediaWriter.h
index cd4af4d..80c5358 100644
--- a/media/libstagefright/include/media/stagefright/MediaWriter.h
+++ b/media/libstagefright/include/media/stagefright/MediaWriter.h
@@ -20,7 +20,7 @@
 
 #include <utils/RefBase.h>
 #include <media/IMediaRecorderClient.h>
-#include <media/IMediaSource.h>
+#include <media/stagefright/MediaSource.h>
 
 namespace android {
 
@@ -32,7 +32,7 @@
           mMaxFileDurationLimitUs(0) {
     }
 
-    virtual status_t addSource(const sp<IMediaSource> &source) = 0;
+    virtual status_t addSource(const sp<MediaSource> &source) = 0;
     virtual bool reachedEOS() = 0;
     virtual status_t start(MetaData *params = NULL) = 0;
     virtual status_t stop() = 0;
diff --git a/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h b/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h
new file mode 100644
index 0000000..96611d1
--- /dev/null
+++ b/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2017, 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 REMOTE_MEDIA_EXTRACTOR_H_
+#define REMOTE_MEDIA_EXTRACTOR_H_
+
+#include <media/IMediaExtractor.h>
+#include <media/stagefright/MediaExtractor.h>
+
+namespace android {
+
+// IMediaExtractor wrapper to the MediaExtractor.
+class RemoteMediaExtractor : public BnMediaExtractor {
+public:
+    static sp<IMediaExtractor> wrap(const sp<MediaExtractor> &extractor);
+
+    virtual ~RemoteMediaExtractor();
+    virtual size_t countTracks();
+    virtual sp<IMediaSource> getTrack(size_t index);
+    virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags = 0);
+    virtual sp<MetaData> getMetaData();
+    virtual status_t getMetrics(Parcel *reply);
+    virtual uint32_t flags() const;
+    virtual char* getDrmTrackInfo(size_t trackID, int * len);
+    virtual void setUID(uid_t uid);
+    virtual status_t setMediaCas(const HInterfaceToken &casToken);
+    virtual const char * name();
+    virtual void release();
+
+private:
+    sp<MediaExtractor> mExtractor;
+
+    explicit RemoteMediaExtractor(const sp<MediaExtractor> &extractor);
+
+    DISALLOW_EVIL_CONSTRUCTORS(RemoteMediaExtractor);
+};
+
+}  // namespace android
+
+#endif  // REMOTE_MEDIA_EXTRACTOR_H_
diff --git a/media/libstagefright/include/media/stagefright/RemoteMediaSource.h b/media/libstagefright/include/media/stagefright/RemoteMediaSource.h
new file mode 100644
index 0000000..2731114
--- /dev/null
+++ b/media/libstagefright/include/media/stagefright/RemoteMediaSource.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2017, 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 REMOTE_MEDIA_SOURCE_H_
+#define REMOTE_MEDIA_SOURCE_H_
+
+#include <media/IMediaSource.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/foundation/ABase.h>
+
+namespace android {
+
+// IMediaSrouce wrapper to the MediaSource.
+class RemoteMediaSource : public BnMediaSource {
+public:
+    static sp<IMediaSource> wrap(const sp<MediaSource> &source);
+    virtual ~RemoteMediaSource();
+    virtual status_t start(MetaData *params = NULL);
+    virtual status_t stop();
+    virtual sp<MetaData> getFormat();
+    virtual status_t read(
+            MediaBuffer **buffer, const ReadOptions *options = NULL);
+    virtual status_t pause();
+    virtual status_t setBuffers(const Vector<MediaBuffer *> &buffers);
+    virtual status_t setStopTimeUs(int64_t stopTimeUs);
+
+private:
+    sp<MediaSource> mSource;
+
+    explicit RemoteMediaSource(const sp<MediaSource> &source);
+
+    DISALLOW_EVIL_CONSTRUCTORS(RemoteMediaSource);
+};
+
+}  // namespace android
+
+#endif  // REMOTE_MEDIA_SOURCE_H_
diff --git a/media/libstagefright/include/media/stagefright/SimpleDecodingSource.h b/media/libstagefright/include/media/stagefright/SimpleDecodingSource.h
index a000fde..b8d141a 100644
--- a/media/libstagefright/include/media/stagefright/SimpleDecodingSource.h
+++ b/media/libstagefright/include/media/stagefright/SimpleDecodingSource.h
@@ -45,12 +45,12 @@
     // does not support secure input or pausing.
     // if |desiredCodec| is given, use this specific codec.
     static sp<SimpleDecodingSource> Create(
-            const sp<IMediaSource> &source, uint32_t flags,
+            const sp<MediaSource> &source, uint32_t flags,
             const sp<ANativeWindow> &nativeWindow,
             const char *desiredCodec = NULL);
 
     static sp<SimpleDecodingSource> Create(
-            const sp<IMediaSource> &source, uint32_t flags = 0);
+            const sp<MediaSource> &source, uint32_t flags = 0);
 
     virtual ~SimpleDecodingSource();
 
@@ -73,11 +73,11 @@
 private:
     // Construct this using a codec, source and looper.
     SimpleDecodingSource(
-            const sp<MediaCodec> &codec, const sp<IMediaSource> &source, const sp<ALooper> &looper,
+            const sp<MediaCodec> &codec, const sp<MediaSource> &source, const sp<ALooper> &looper,
             bool usingSurface, bool isVorbis, const sp<AMessage> &format);
 
     sp<MediaCodec> mCodec;
-    sp<IMediaSource> mSource;
+    sp<MediaSource> mSource;
     sp<ALooper> mLooper;
     bool mUsingSurface;
     bool mIsVorbis;
diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp
index 4b38906..487603c 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.cpp
+++ b/media/libstagefright/matroska/MatroskaExtractor.cpp
@@ -899,7 +899,7 @@
     return mTracks.size();
 }
 
-sp<IMediaSource> MatroskaExtractor::getTrack(size_t index) {
+sp<MediaSource> MatroskaExtractor::getTrack(size_t index) {
     if (index >= mTracks.size()) {
         return NULL;
     }
diff --git a/media/libstagefright/matroska/MatroskaExtractor.h b/media/libstagefright/matroska/MatroskaExtractor.h
index 19775ce..832463f 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.h
+++ b/media/libstagefright/matroska/MatroskaExtractor.h
@@ -38,7 +38,7 @@
 
     virtual size_t countTracks();
 
-    virtual sp<IMediaSource> getTrack(size_t index);
+    virtual sp<MediaSource> getTrack(size_t index);
 
     virtual sp<MetaData> getTrackMetaData(
             size_t index, uint32_t flags);
diff --git a/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
index 078a5f0..0f18fac 100644
--- a/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
@@ -125,7 +125,7 @@
     return mTracks.size();
 }
 
-sp<IMediaSource> MPEG2PSExtractor::getTrack(size_t index) {
+sp<MediaSource> MPEG2PSExtractor::getTrack(size_t index) {
     if (index >= mTracks.size()) {
         return NULL;
     }
diff --git a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
index 9d684e0..b66af7b 100644
--- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
@@ -129,7 +129,7 @@
     return mSourceImpls.size();
 }
 
-sp<IMediaSource> MPEG2TSExtractor::getTrack(size_t index) {
+sp<MediaSource> MPEG2TSExtractor::getTrack(size_t index) {
     if (index >= mSourceImpls.size()) {
         return NULL;
     }
diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp
index 3266439..4b624f2 100644
--- a/media/libstagefright/omx/tests/OMXHarness.cpp
+++ b/media/libstagefright/omx/tests/OMXHarness.cpp
@@ -543,7 +543,7 @@
     return NULL;
 }
 
-static sp<IMediaSource> CreateSourceForMime(const char *mime) {
+static sp<MediaSource> CreateSourceForMime(const char *mime) {
     const char *url = GetURLForMime(mime);
 
     if (url == NULL) {
@@ -564,7 +564,7 @@
         CHECK(meta->findCString(kKeyMIMEType, &trackMime));
 
         if (!strcasecmp(mime, trackMime)) {
-            return extractor->getTrack(i);
+            return MediaSource::CreateFromIMediaSource(extractor->getTrack(i));
         }
     }
 
@@ -610,7 +610,7 @@
         return OK;
     }
 
-    sp<IMediaSource> source = CreateSourceForMime(mime);
+    sp<MediaSource> source = CreateSourceForMime(mime);
 
     if (source == NULL) {
         printf("  * Unable to open test content for type '%s', "
@@ -620,14 +620,14 @@
         return OK;
     }
 
-    sp<IMediaSource> seekSource = CreateSourceForMime(mime);
+    sp<MediaSource> seekSource = CreateSourceForMime(mime);
     if (source == NULL || seekSource == NULL) {
         return UNKNOWN_ERROR;
     }
 
     CHECK_EQ(seekSource->start(), (status_t)OK);
 
-    sp<IMediaSource> codec = SimpleDecodingSource::Create(
+    sp<MediaSource> codec = SimpleDecodingSource::Create(
             source, 0 /* flags */, NULL /* nativeWindow */, componentName);
 
     CHECK(codec != NULL);
diff --git a/media/libstagefright/rtsp/ARTPWriter.cpp b/media/libstagefright/rtsp/ARTPWriter.cpp
index 1f6b6f7..56c4aa6 100644
--- a/media/libstagefright/rtsp/ARTPWriter.cpp
+++ b/media/libstagefright/rtsp/ARTPWriter.cpp
@@ -104,7 +104,7 @@
     mFd = -1;
 }
 
-status_t ARTPWriter::addSource(const sp<IMediaSource> &source) {
+status_t ARTPWriter::addSource(const sp<MediaSource> &source) {
     mSource = source;
     return OK;
 }
diff --git a/media/libstagefright/rtsp/ARTPWriter.h b/media/libstagefright/rtsp/ARTPWriter.h
index 3c7042e..92a64f2 100644
--- a/media/libstagefright/rtsp/ARTPWriter.h
+++ b/media/libstagefright/rtsp/ARTPWriter.h
@@ -37,7 +37,7 @@
 struct ARTPWriter : public MediaWriter {
     explicit ARTPWriter(int fd);
 
-    virtual status_t addSource(const sp<IMediaSource> &source);
+    virtual status_t addSource(const sp<MediaSource> &source);
     virtual bool reachedEOS();
     virtual status_t start(MetaData *params);
     virtual status_t stop();
@@ -72,7 +72,7 @@
     int mRTCPFd;
 #endif
 
-    sp<IMediaSource> mSource;
+    sp<MediaSource> mSource;
     sp<ALooper> mLooper;
     sp<AHandlerReflector<ARTPWriter> > mReflector;
 
diff --git a/media/libstagefright/webm/WebmFrameThread.cpp b/media/libstagefright/webm/WebmFrameThread.cpp
index 71bfbc9..420890b 100644
--- a/media/libstagefright/webm/WebmFrameThread.cpp
+++ b/media/libstagefright/webm/WebmFrameThread.cpp
@@ -252,7 +252,7 @@
 }
 
 WebmFrameMediaSourceThread::WebmFrameMediaSourceThread(
-        const sp<IMediaSource>& source,
+        const sp<MediaSource>& source,
         int type,
         LinkedBlockingQueue<const sp<WebmFrame> >& sink,
         uint64_t timeCodeScale,
diff --git a/media/libstagefright/webm/WebmFrameThread.h b/media/libstagefright/webm/WebmFrameThread.h
index 528984f..d65d9b7 100644
--- a/media/libstagefright/webm/WebmFrameThread.h
+++ b/media/libstagefright/webm/WebmFrameThread.h
@@ -123,7 +123,7 @@
 class WebmFrameMediaSourceThread: public WebmFrameSourceThread {
 public:
     WebmFrameMediaSourceThread(
-            const sp<IMediaSource>& source,
+            const sp<MediaSource>& source,
             int type,
             LinkedBlockingQueue<const sp<WebmFrame> >& sink,
             uint64_t timeCodeScale,
@@ -142,7 +142,7 @@
     }
 
 private:
-    const sp<IMediaSource> mSource;
+    const sp<MediaSource> mSource;
     const uint64_t mTimeCodeScale;
     uint64_t mStartTimeUs;
 
diff --git a/media/libstagefright/webm/WebmWriter.cpp b/media/libstagefright/webm/WebmWriter.cpp
index d6c6930..4d73eb8 100644
--- a/media/libstagefright/webm/WebmWriter.cpp
+++ b/media/libstagefright/webm/WebmWriter.cpp
@@ -360,7 +360,7 @@
     return err;
 }
 
-status_t WebmWriter::addSource(const sp<IMediaSource> &source) {
+status_t WebmWriter::addSource(const sp<MediaSource> &source) {
     Mutex::Autolock l(mLock);
     if (mStarted) {
         ALOGE("Attempt to add source AFTER recording is started");
diff --git a/media/libstagefright/webm/WebmWriter.h b/media/libstagefright/webm/WebmWriter.h
index 9f3b19f..ed5bc4c 100644
--- a/media/libstagefright/webm/WebmWriter.h
+++ b/media/libstagefright/webm/WebmWriter.h
@@ -40,7 +40,7 @@
     ~WebmWriter() { reset(); }
 
 
-    virtual status_t addSource(const sp<IMediaSource> &source);
+    virtual status_t addSource(const sp<MediaSource> &source);
     virtual status_t start(MetaData *param = NULL);
     virtual status_t stop();
     virtual status_t pause();
@@ -85,7 +85,7 @@
         const char *mName;
         sp<WebmElement> (*mMakeTrack)(const sp<MetaData>&);
 
-        sp<IMediaSource> mSource;
+        sp<MediaSource> mSource;
         sp<WebmElement> mTrackEntry;
         sp<WebmFrameSourceThread> mThread;
         LinkedBlockingQueue<const sp<WebmFrame> > mSink;
diff --git a/services/mediaextractor/MediaExtractorService.cpp b/services/mediaextractor/MediaExtractorService.cpp
index 08cbef6..50a4191 100644
--- a/services/mediaextractor/MediaExtractorService.cpp
+++ b/services/mediaextractor/MediaExtractorService.cpp
@@ -33,17 +33,18 @@
 
     sp<DataSource> localSource = DataSource::CreateFromIDataSource(remoteSource);
 
-    sp<IMediaExtractor> ret = MediaExtractor::CreateFromService(localSource, mime);
+    sp<MediaExtractor> extractor = MediaExtractor::CreateFromService(localSource, mime);
 
     ALOGV("extractor service created %p (%s)",
-            ret.get(),
-            ret == NULL ? "" : ret->name());
+            extractor.get(),
+            extractor == nullptr ? "" : extractor->name());
 
-    if (ret != NULL) {
+    if (extractor != nullptr) {
+        sp<IMediaExtractor> ret = extractor->asIMediaExtractor();
         registerMediaExtractor(ret, localSource, mime);
+        return ret;
     }
-
-    return ret;
+    return nullptr;
 }
 
 sp<IDataSource> MediaExtractorService::makeIDataSource(int fd, int64_t offset, int64_t length)