Extractor service

Run extractors in a separate process. Currently all data is copied through a
binder transaction, and WVMExtractor is still run in the mediaserver process.

Change-Id: Ic5dbce87126dd321ad792f4dd540c2ff6b068d13
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index be88aa0..285c33e 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -33,11 +33,14 @@
     IMediaHTTPConnection.cpp \
     IMediaHTTPService.cpp \
     IMediaLogService.cpp \
+    IMediaExtractor.cpp           \
+    IMediaExtractorService.cpp \
     IMediaPlayerService.cpp \
     IMediaPlayerClient.cpp \
     IMediaRecorderClient.cpp \
     IMediaPlayer.cpp \
     IMediaRecorder.cpp \
+    IMediaSource.cpp \
     IRemoteDisplay.cpp \
     IRemoteDisplayClient.cpp \
     IResourceManagerClient.cpp \
diff --git a/media/libmedia/IMediaExtractor.cpp b/media/libmedia/IMediaExtractor.cpp
new file mode 100644
index 0000000..85362fd
--- /dev/null
+++ b/media/libmedia/IMediaExtractor.cpp
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2009 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 "BpMediaExtractor"
+#include <utils/Log.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <binder/Parcel.h>
+#include <media/IMediaExtractor.h>
+#include <media/stagefright/MetaData.h>
+
+namespace android {
+
+enum {
+    COUNTTRACKS = IBinder::FIRST_CALL_TRANSACTION,
+    GETTRACK,
+    GETTRACKMETADATA,
+    GETMETADATA,
+    FLAGS,
+    SETDRMFLAG,
+    GETDRMFLAG,
+    GETDRMTRACKINFO,
+    SETUID,
+    NAME
+};
+
+class BpMediaExtractor : public BpInterface<IMediaExtractor> {
+public:
+    BpMediaExtractor(const sp<IBinder>& impl)
+        : BpInterface<IMediaExtractor>(impl)
+    {
+    }
+
+    virtual size_t countTracks() {
+        ALOGV("countTracks");
+        Parcel data, reply;
+        data.writeInterfaceToken(BpMediaExtractor::getInterfaceDescriptor());
+        status_t ret = remote()->transact(COUNTTRACKS, data, &reply);
+        size_t numTracks = 0;
+        if (ret == NO_ERROR) {
+            numTracks = reply.readUint32();
+        }
+        return numTracks;
+    }
+    virtual sp<IMediaSource> getTrack(size_t index) {
+        ALOGV("getTrack(%zu)", index);
+        Parcel data, reply;
+        data.writeInterfaceToken(BpMediaExtractor::getInterfaceDescriptor());
+        data.writeUint32(index);
+        status_t ret = remote()->transact(GETTRACK, data, &reply);
+        if (ret == NO_ERROR) {
+            return interface_cast<IMediaSource>(reply.readStrongBinder());
+        }
+        return NULL;
+    }
+
+    virtual sp<MetaData> getTrackMetaData(
+            size_t index, uint32_t flags) {
+        ALOGV("getTrackMetaData(%zu, %u)", index, flags);
+        Parcel data, reply;
+        data.writeInterfaceToken(BpMediaExtractor::getInterfaceDescriptor());
+        data.writeUint32(index);
+        data.writeUint32(flags);
+        status_t ret = remote()->transact(GETTRACKMETADATA, data, &reply);
+        if (ret == NO_ERROR) {
+            return MetaData::createFromParcel(reply);
+        }
+        return NULL;
+    }
+
+    virtual sp<MetaData> getMetaData() {
+        ALOGV("getMetaData");
+        Parcel data, reply;
+        data.writeInterfaceToken(BpMediaExtractor::getInterfaceDescriptor());
+        status_t ret = remote()->transact(GETMETADATA, data, &reply);
+        if (ret == NO_ERROR) {
+            return MetaData::createFromParcel(reply);
+        }
+        return NULL;
+    }
+
+    virtual uint32_t flags() const {
+        ALOGV("flags NOT IMPLEMENTED");
+        return 0;
+    }
+
+    virtual void setDrmFlag(bool flag __unused) {
+        ALOGV("setDrmFlag NOT IMPLEMENTED");
+    }
+    virtual bool getDrmFlag() {
+        ALOGV("getDrmFlag NOT IMPLEMENTED");
+       return false;
+    }
+    virtual char* getDrmTrackInfo(size_t trackID __unused, int *len __unused) {
+        ALOGV("getDrmTrackInfo NOT IMPLEMENTED");
+        return NULL;
+    }
+    virtual void setUID(uid_t uid __unused) {
+        ALOGV("setUID NOT IMPLEMENTED");
+    }
+
+    virtual const char * name() {
+        ALOGV("name NOT IMPLEMENTED");
+        return NULL;
+    }
+};
+
+IMPLEMENT_META_INTERFACE(MediaExtractor, "android.media.IMediaExtractor");
+
+#undef LOG_TAG
+#define LOG_TAG "BnMediaExtractor"
+
+status_t BnMediaExtractor::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch (code) {
+        case COUNTTRACKS: {
+            ALOGV("countTracks");
+            CHECK_INTERFACE(IMediaExtractor, data, reply);
+            size_t numTracks = countTracks();
+            if (numTracks > INT32_MAX) {
+                numTracks = 0;
+            }
+            reply->writeUint32(uint32_t(numTracks));
+            return NO_ERROR;
+        }
+        case GETTRACK: {
+            ALOGV("getTrack()");
+            CHECK_INTERFACE(IMediaExtractor, data, reply);
+            uint32_t idx;
+            if (data.readUint32(&idx) == NO_ERROR) {
+                return reply->writeStrongBinder(IInterface::asBinder(getTrack((size_t(idx)))));
+            }
+            return UNKNOWN_ERROR;
+        }
+        case GETTRACKMETADATA: {
+            ALOGV("getTrackMetaData");
+            CHECK_INTERFACE(IMediaExtractor, data, reply);
+            uint32_t idx;
+            uint32_t flags;
+            if (data.readUint32(&idx) == NO_ERROR &&
+                    data.readUint32(&flags) == NO_ERROR) {
+                sp<MetaData> meta = getTrackMetaData(idx, flags);
+                meta->writeToParcel(*reply);
+                return NO_ERROR;
+            }
+            return UNKNOWN_ERROR;
+        }
+        case GETMETADATA: {
+            ALOGV("getMetaData");
+            CHECK_INTERFACE(IMediaExtractor, data, reply);
+            sp<MetaData> meta = getMetaData();
+            if (meta != NULL) {
+                meta->writeToParcel(*reply);
+                return NO_ERROR;
+            }
+            return UNKNOWN_ERROR;
+        }
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+
+}  // namespace android
+
diff --git a/media/libmedia/IMediaExtractorService.cpp b/media/libmedia/IMediaExtractorService.cpp
new file mode 100644
index 0000000..51a3c1a
--- /dev/null
+++ b/media/libmedia/IMediaExtractorService.cpp
@@ -0,0 +1,81 @@
+/*
+**
+** Copyright 2007, 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_TAG "IMediaExtractorService"
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <binder/Parcel.h>
+#include <media/IMediaExtractorService.h>
+
+namespace android {
+
+enum {
+    MAKE_EXTRACTOR = IBinder::FIRST_CALL_TRANSACTION
+};
+
+class BpMediaExtractorService : public BpInterface<IMediaExtractorService>
+{
+public:
+    BpMediaExtractorService(const sp<IBinder>& impl)
+        : BpInterface<IMediaExtractorService>(impl)
+    {
+    }
+
+    virtual sp<IMediaExtractor> makeExtractor(const sp<IDataSource> &source, const char *mime) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMediaExtractorService::getInterfaceDescriptor());
+        data.writeStrongBinder(IInterface::asBinder(source));
+        if (mime != NULL) {
+            data.writeCString(mime);
+        }
+        status_t ret = remote()->transact(MAKE_EXTRACTOR, data, &reply);
+        if (ret == NO_ERROR) {
+            return interface_cast<IMediaExtractor>(reply.readStrongBinder());
+        }
+        return NULL;
+    }
+
+};
+
+IMPLEMENT_META_INTERFACE(MediaExtractorService, "android.media.IMediaExtractorService");
+
+// ----------------------------------------------------------------------
+
+status_t BnMediaExtractorService::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch (code) {
+
+        case MAKE_EXTRACTOR: {
+            CHECK_INTERFACE(IMediaExtractorService, data, reply);
+            sp<IDataSource> source = interface_cast<IDataSource>(data.readStrongBinder());
+            const char *mime = data.readCString();
+            sp<IMediaExtractor> ex = makeExtractor(source, mime);
+            reply->writeStrongBinder(IInterface::asBinder(ex));
+            return NO_ERROR;
+        }
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+} // namespace android
diff --git a/media/libmedia/IMediaSource.cpp b/media/libmedia/IMediaSource.cpp
new file mode 100644
index 0000000..aec6255
--- /dev/null
+++ b/media/libmedia/IMediaSource.cpp
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2009 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 "BpMediaSource"
+#include <utils/Log.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <binder/Parcel.h>
+#include <media/IMediaSource.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MetaData.h>
+
+namespace android {
+
+enum {
+    START = IBinder::FIRST_CALL_TRANSACTION,
+    STOP,
+    PAUSE,
+    GETFORMAT,
+    READ
+};
+
+class BpMediaSource : public BpInterface<IMediaSource> {
+public:
+    BpMediaSource(const sp<IBinder>& impl)
+        : BpInterface<IMediaSource>(impl)
+    {
+    }
+
+    virtual status_t start(MetaData *params) {
+        ALOGV("start");
+        Parcel data, reply;
+        data.writeInterfaceToken(BpMediaSource::getInterfaceDescriptor());
+        if (params) {
+            params->writeToParcel(data);
+        }
+        status_t ret = remote()->transact(START, data, &reply);
+        if (ret == NO_ERROR && params) {
+            ALOGW("ignoring potentially modified MetaData from start");
+            ALOGW("input:");
+            params->dumpToLog();
+            sp<MetaData> meta = MetaData::createFromParcel(reply);
+            ALOGW("output:");
+            meta->dumpToLog();
+        }
+        return ret;
+    }
+
+    virtual status_t stop() {
+        ALOGV("stop");
+        Parcel data, reply;
+        data.writeInterfaceToken(BpMediaSource::getInterfaceDescriptor());
+        return remote()->transact(STOP, data, &reply);
+    }
+
+    virtual sp<MetaData> getFormat() {
+        ALOGV("getFormat");
+        Parcel data, reply;
+        data.writeInterfaceToken(BpMediaSource::getInterfaceDescriptor());
+        status_t ret = remote()->transact(GETFORMAT, data, &reply);
+        if (ret == NO_ERROR) {
+            mMetaData = MetaData::createFromParcel(reply);
+            return mMetaData;
+        }
+        return NULL;
+    }
+
+    virtual status_t read(MediaBuffer **buffer, const ReadOptions *options) {
+        ALOGV("read");
+        Parcel data, reply;
+        data.writeInterfaceToken(BpMediaSource::getInterfaceDescriptor());
+        if (options) {
+            data.writeByteArray(sizeof(*options), (uint8_t*) options);
+        }
+        status_t ret = remote()->transact(READ, data, &reply);
+        if (ret != NO_ERROR) {
+            return ret;
+        }
+        // wrap the returned data in a MediaBuffer
+        // XXX use a group, and use shared memory for transfer
+        ret = reply.readInt32();
+        int32_t len = reply.readInt32();
+        if (len < 0) {
+            ALOGV("got status %d and len %d, returning NULL buffer", ret, len);
+            *buffer = NULL;
+        } else {
+            ALOGV("got status %d and len %d", ret, len);
+            *buffer = new MediaBuffer(len);
+            reply.read((*buffer)->data(), len);
+            (*buffer)->meta_data()->updateFromParcel(reply);
+        }
+        return ret;
+    }
+
+    virtual status_t pause() {
+        ALOGV("pause");
+        Parcel data, reply;
+        data.writeInterfaceToken(BpMediaSource::getInterfaceDescriptor());
+        return remote()->transact(PAUSE, data, &reply);
+    }
+
+    virtual status_t setBuffers(const Vector<MediaBuffer *> & buffers __unused) {
+        ALOGV("setBuffers NOT IMPLEMENTED");
+        return ERROR_UNSUPPORTED; // default
+    }
+
+private:
+    // NuPlayer passes pointers-to-metadata around, so we use this to keep the metadata alive
+    // XXX: could we use this for caching, or does metadata change on the fly?
+    sp<MetaData> mMetaData;
+
+};
+
+IMPLEMENT_META_INTERFACE(MediaSource, "android.media.IMediaSource");
+
+#undef LOG_TAG
+#define LOG_TAG "BnMediaSource"
+
+status_t BnMediaSource::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch (code) {
+        case START: {
+            ALOGV("start");
+            CHECK_INTERFACE(IMediaSource, data, reply);
+            sp<MetaData> meta;
+            if (data.dataAvail()) {
+                meta = MetaData::createFromParcel(data);
+            }
+            status_t ret = start(meta.get());
+            if (ret == NO_ERROR && meta != NULL) {
+                meta->writeToParcel(*reply);
+            }
+            return ret;
+        }
+        case STOP: {
+            ALOGV("stop");
+            CHECK_INTERFACE(IMediaSource, data, reply);
+            return stop();
+        }
+        case PAUSE: {
+            ALOGV("pause");
+            CHECK_INTERFACE(IMediaSource, data, reply);
+            return pause();
+        }
+        case GETFORMAT: {
+            ALOGV("getFormat");
+            CHECK_INTERFACE(IMediaSource, data, reply);
+            sp<MetaData> meta = getFormat();
+            if (meta != NULL) {
+                meta->writeToParcel(*reply);
+                return NO_ERROR;
+            }
+            return UNKNOWN_ERROR;
+        }
+        case READ: {
+            ALOGV("read");
+            CHECK_INTERFACE(IMediaSource, data, reply);
+            status_t ret;
+            MediaBuffer *buf = NULL;
+            ReadOptions opts;
+            uint32_t len;
+            if (data.readUint32(&len) == NO_ERROR &&
+                    len == sizeof(opts) && data.read((void*)&opts, len) == NO_ERROR) {
+                ret = read(&buf, &opts);
+            } else {
+                ret = read(&buf, NULL);
+            }
+            // return data inside binder for now
+            // XXX return data using shared memory
+            reply->writeInt32(ret);
+            if (buf != NULL) {
+                ALOGV("ret %d, buflen %zu", ret, buf->range_length());
+                reply->writeByteArray(buf->range_length(), (uint8_t*)buf->data() + buf->range_offset());
+                buf->meta_data()->writeToParcel(*reply);
+                buf->release();
+            } else {
+                ALOGV("ret %d, buf %p", ret, buf);
+                reply->writeInt32(-1);
+            }
+            return NO_ERROR;
+        }
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+IMediaSource::ReadOptions::ReadOptions() {
+    reset();
+}
+
+void IMediaSource::ReadOptions::reset() {
+    mOptions = 0;
+    mSeekTimeUs = 0;
+    mLatenessUs = 0;
+    mNonBlocking = false;
+}
+
+void IMediaSource::ReadOptions::setNonBlocking() {
+    mNonBlocking = true;
+}
+
+void IMediaSource::ReadOptions::clearNonBlocking() {
+    mNonBlocking = false;
+}
+
+bool IMediaSource::ReadOptions::getNonBlocking() const {
+    return mNonBlocking;
+}
+
+void IMediaSource::ReadOptions::setSeekTo(int64_t time_us, SeekMode mode) {
+    mOptions |= kSeekTo_Option;
+    mSeekTimeUs = time_us;
+    mSeekMode = mode;
+}
+
+void IMediaSource::ReadOptions::clearSeekTo() {
+    mOptions &= ~kSeekTo_Option;
+    mSeekTimeUs = 0;
+    mSeekMode = SEEK_CLOSEST_SYNC;
+}
+
+bool IMediaSource::ReadOptions::getSeekTo(
+        int64_t *time_us, SeekMode *mode) const {
+    *time_us = mSeekTimeUs;
+    *mode = mSeekMode;
+    return (mOptions & kSeekTo_Option) != 0;
+}
+
+void IMediaSource::ReadOptions::setLateBy(int64_t lateness_us) {
+    mLatenessUs = lateness_us;
+}
+
+int64_t IMediaSource::ReadOptions::getLateBy() const {
+    return mLatenessUs;
+}
+
+
+}  // namespace android
+
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 92e3d2e..4d3ccd2 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -135,7 +135,7 @@
 }
 
 status_t NuPlayer::GenericSource::initFromDataSource() {
-    sp<MediaExtractor> extractor;
+    sp<IMediaExtractor> extractor;
     String8 mimeType;
     float confidence;
     sp<AMessage> dummy;
@@ -210,7 +210,7 @@
     }
 
     for (size_t i = 0; i < numtracks; ++i) {
-        sp<MediaSource> track = extractor->getTrack(i);
+        sp<IMediaSource> track = extractor->getTrack(i);
         if (track == NULL) {
             continue;
         }
@@ -791,7 +791,7 @@
       {
           int32_t trackIndex;
           CHECK(msg->findInt32("trackIndex", &trackIndex));
-          const sp<MediaSource> source = mSources.itemAt(trackIndex);
+          const sp<IMediaSource> source = mSources.itemAt(trackIndex);
 
           Track* track;
           const char *mime;
@@ -1034,7 +1034,7 @@
 }
 
 sp<MetaData> NuPlayer::GenericSource::doGetFormatMeta(bool audio) const {
-    sp<MediaSource> source = audio ? mAudioTrack.mSource : mVideoTrack.mSource;
+    sp<IMediaSource> source = audio ? mAudioTrack.mSource : mVideoTrack.mSource;
 
     if (source == NULL) {
         return NULL;
@@ -1282,7 +1282,7 @@
         return OK;
     }
 
-    const sp<MediaSource> source = mSources.itemAt(trackIndex);
+    const sp<IMediaSource> source = mSources.itemAt(trackIndex);
     sp<MetaData> meta = source->getFormat();
     const char *mime;
     CHECK(meta->findCString(kKeyMIMEType, &mime));
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h
index 035cc1f..2db5557 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -107,11 +107,11 @@
 
     struct Track {
         size_t mIndex;
-        sp<MediaSource> mSource;
+        sp<IMediaSource> mSource;
         sp<AnotherPacketSource> mPackets;
     };
 
-    Vector<sp<MediaSource> > mSources;
+    Vector<sp<IMediaSource> > mSources;
     Track mAudioTrack;
     int64_t mAudioTimeUs;
     int64_t mAudioLastDequeueTimeUs;
diff --git a/media/libstagefright/AACExtractor.cpp b/media/libstagefright/AACExtractor.cpp
index 45e8a30..19efc53 100644
--- a/media/libstagefright/AACExtractor.cpp
+++ b/media/libstagefright/AACExtractor.cpp
@@ -211,7 +211,7 @@
     return mInitCheck == OK ? 1 : 0;
 }
 
-sp<MediaSource> AACExtractor::getTrack(size_t index) {
+sp<IMediaSource> 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 9d90dbd..8b1e1c3 100644
--- a/media/libstagefright/AACWriter.cpp
+++ b/media/libstagefright/AACWriter.cpp
@@ -67,7 +67,7 @@
 }
 
 
-status_t AACWriter::addSource(const sp<MediaSource> &source) {
+status_t AACWriter::addSource(const sp<IMediaSource> &source) {
     if (mInitCheck != OK) {
         return mInitCheck;
     }
diff --git a/media/libstagefright/AMRExtractor.cpp b/media/libstagefright/AMRExtractor.cpp
index 4a66d66..1458802 100644
--- a/media/libstagefright/AMRExtractor.cpp
+++ b/media/libstagefright/AMRExtractor.cpp
@@ -180,7 +180,7 @@
     return mInitCheck == OK ? 1 : 0;
 }
 
-sp<MediaSource> AMRExtractor::getTrack(size_t index) {
+sp<IMediaSource> 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 f53d7f0..961b57f 100644
--- a/media/libstagefright/AMRWriter.cpp
+++ b/media/libstagefright/AMRWriter.cpp
@@ -54,7 +54,7 @@
     return mInitCheck;
 }
 
-status_t AMRWriter::addSource(const sp<MediaSource> &source) {
+status_t AMRWriter::addSource(const sp<IMediaSource> &source) {
     if (mInitCheck != OK) {
         return mInitCheck;
     }
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 1c44285..ec06711 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -31,7 +31,6 @@
         MPEG4Extractor.cpp                \
         MPEG4Writer.cpp                   \
         MediaAdapter.cpp                  \
-        MediaBuffer.cpp                   \
         MediaBufferGroup.cpp              \
         MediaClock.cpp                    \
         MediaCodec.cpp                    \
@@ -45,7 +44,6 @@
         http/MediaHTTP.cpp                \
         MediaMuxer.cpp                    \
         MediaSource.cpp                   \
-        MetaData.cpp                      \
         NuCachedSource2.cpp               \
         NuMediaExtractor.cpp              \
         OMXClient.cpp                     \
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index dd9d393..c977958 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -71,7 +71,7 @@
     }
 }
 
-void AudioPlayer::setSource(const sp<MediaSource> &source) {
+void AudioPlayer::setSource(const sp<IMediaSource> &source) {
     CHECK(mSource == NULL);
     mSource = source;
 }
@@ -358,7 +358,7 @@
     // When offloading, the OMX component is not used so this hack
     // is not needed
     if (!useOffload()) {
-        wp<MediaSource> tmp = mSource;
+        wp<IMediaSource> tmp = mSource;
         mSource.clear();
         while (tmp.promote() != NULL) {
             usleep(1000);
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index b0efebc..f5e9def 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -370,7 +370,7 @@
 
 status_t AwesomePlayer::setDataSource_l(
         const sp<DataSource> &dataSource) {
-    sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
+    sp<IMediaExtractor> extractor = MediaExtractor::Create(dataSource);
 
     if (extractor == NULL) {
         return UNKNOWN_ERROR;
@@ -393,7 +393,7 @@
     }
 }
 
-status_t AwesomePlayer::setDataSource_l(const sp<MediaExtractor> &extractor) {
+status_t AwesomePlayer::setDataSource_l(const sp<IMediaExtractor> &extractor) {
     // Attempt to approximate overall stream bitrate by summing all
     // tracks' individual bitrates, if not all of them advertise bitrate,
     // we have to fail.
@@ -1354,7 +1354,7 @@
     // The following hack is necessary to ensure that the OMX
     // component is completely released by the time we may try
     // to instantiate it again.
-    wp<MediaSource> tmp = mVideoSource;
+    wp<IMediaSource> tmp = mVideoSource;
     mVideoSource.clear();
     while (tmp.promote() != NULL) {
         usleep(1000);
@@ -1518,13 +1518,13 @@
     }
 }
 
-void AwesomePlayer::setAudioSource(sp<MediaSource> source) {
+void AwesomePlayer::setAudioSource(sp<IMediaSource> source) {
     CHECK(source != NULL);
 
     mAudioTrack = source;
 }
 
-void AwesomePlayer::addTextSource_l(size_t trackIndex, const sp<MediaSource>& source) {
+void AwesomePlayer::addTextSource_l(size_t trackIndex, const sp<IMediaSource>& source) {
     CHECK(source != NULL);
 
     if (mTextDriver == NULL) {
@@ -1610,7 +1610,7 @@
     return mAudioSource != NULL ? OK : UNKNOWN_ERROR;
 }
 
-void AwesomePlayer::setVideoSource(sp<MediaSource> source) {
+void AwesomePlayer::setVideoSource(sp<IMediaSource> source) {
     CHECK(source != NULL);
 
     mVideoTrack = source;
@@ -2393,7 +2393,7 @@
         return UNKNOWN_ERROR;
     }
 
-    sp<MediaExtractor> extractor;
+    sp<IMediaExtractor> extractor;
 
     if (isWidevineStreaming) {
         String8 mimeType;
@@ -2696,7 +2696,7 @@
 }
 
 status_t AwesomePlayer::selectAudioTrack_l(
-        const sp<MediaSource>& source, size_t trackIndex) {
+        const sp<IMediaSource>& source, size_t trackIndex) {
 
     ALOGI("selectAudioTrack_l: trackIndex=%zu, mFlags=0x%x", trackIndex, mFlags);
 
diff --git a/media/libstagefright/DRMExtractor.cpp b/media/libstagefright/DRMExtractor.cpp
index 9cb6e86..255dcd0 100644
--- a/media/libstagefright/DRMExtractor.cpp
+++ b/media/libstagefright/DRMExtractor.cpp
@@ -35,7 +35,7 @@
 
 class DRMSource : public MediaSource {
 public:
-    DRMSource(const sp<MediaSource> &mediaSource,
+    DRMSource(const sp<IMediaSource> &mediaSource,
             const sp<DecryptHandle> &decryptHandle,
             DrmManagerClient *managerClient,
             int32_t trackId, DrmBuffer *ipmpBox);
@@ -50,7 +50,7 @@
     virtual ~DRMSource();
 
 private:
-    sp<MediaSource> mOriginalMediaSource;
+    sp<IMediaSource> mOriginalMediaSource;
     sp<DecryptHandle> mDecryptHandle;
     DrmManagerClient* mDrmManagerClient;
     size_t mTrackId;
@@ -64,7 +64,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-DRMSource::DRMSource(const sp<MediaSource> &mediaSource,
+DRMSource::DRMSource(const sp<IMediaSource> &mediaSource,
         const sp<DecryptHandle> &decryptHandle,
         DrmManagerClient *managerClient,
         int32_t trackId, DrmBuffer *ipmpBox)
@@ -247,8 +247,8 @@
     return mOriginalExtractor->countTracks();
 }
 
-sp<MediaSource> DRMExtractor::getTrack(size_t index) {
-    sp<MediaSource> originalMediaSource = mOriginalExtractor->getTrack(index);
+sp<IMediaSource> DRMExtractor::getTrack(size_t index) {
+    sp<IMediaSource> originalMediaSource = mOriginalExtractor->getTrack(index);
     originalMediaSource->getFormat()->setInt32(kKeyIsDRM, 1);
 
     int32_t trackID;
@@ -258,8 +258,9 @@
     ipmpBox.data = mOriginalExtractor->getDrmTrackInfo(trackID, &(ipmpBox.length));
     CHECK(ipmpBox.length > 0);
 
-    return new DRMSource(originalMediaSource, mDecryptHandle, mDrmManagerClient,
-            trackID, &ipmpBox);
+    return interface_cast<IMediaSource>(
+            new DRMSource(originalMediaSource, mDecryptHandle, mDrmManagerClient,
+            trackID, &ipmpBox));
 }
 
 sp<MetaData> DRMExtractor::getTrackMetaData(size_t index, uint32_t flags) {
diff --git a/media/libstagefright/FLACExtractor.cpp b/media/libstagefright/FLACExtractor.cpp
index 89a91f7..6e99d02 100644
--- a/media/libstagefright/FLACExtractor.cpp
+++ b/media/libstagefright/FLACExtractor.cpp
@@ -807,7 +807,7 @@
     return mInitCheck == OK ? 1 : 0;
 }
 
-sp<MediaSource> FLACExtractor::getTrack(size_t index)
+sp<IMediaSource> 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 2e54e8c..7240e1a 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -400,7 +400,7 @@
     return mInitCheck != OK ? 0 : 1;
 }
 
-sp<MediaSource> MP3Extractor::getTrack(size_t index) {
+sp<IMediaSource> 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 ef07aa0..a9e8846 100644
--- a/media/libstagefright/MPEG2TSWriter.cpp
+++ b/media/libstagefright/MPEG2TSWriter.cpp
@@ -35,7 +35,7 @@
 namespace android {
 
 struct MPEG2TSWriter::SourceInfo : public AHandler {
-    SourceInfo(const sp<MediaSource> &source);
+    SourceInfo(const sp<IMediaSource> &source);
 
     void start(const sp<AMessage> &notify);
     void stop();
@@ -69,7 +69,7 @@
         kWhatRead  = 'read',
     };
 
-    sp<MediaSource> mSource;
+    sp<IMediaSource> mSource;
     sp<ALooper> mLooper;
     sp<AMessage> mNotify;
 
@@ -93,7 +93,7 @@
     DISALLOW_EVIL_CONSTRUCTORS(SourceInfo);
 };
 
-MPEG2TSWriter::SourceInfo::SourceInfo(const sp<MediaSource> &source)
+MPEG2TSWriter::SourceInfo::SourceInfo(const sp<IMediaSource> &source)
     : mSource(source),
       mLooper(new ALooper),
       mEOSReceived(false),
@@ -523,7 +523,7 @@
     }
 }
 
-status_t MPEG2TSWriter::addSource(const sp<MediaSource> &source) {
+status_t MPEG2TSWriter::addSource(const sp<IMediaSource> &source) {
     CHECK(!mStarted);
 
     sp<MetaData> meta = source->getFormat();
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index affd830..a6275ba 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -2835,7 +2835,7 @@
     }
 }
 
-sp<MediaSource> MPEG4Extractor::getTrack(size_t index) {
+sp<IMediaSource> 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 78d4fb1..ea4a7ac 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -75,7 +75,7 @@
 
 class MPEG4Writer::Track {
 public:
-    Track(MPEG4Writer *owner, const sp<MediaSource> &source, size_t trackId);
+    Track(MPEG4Writer *owner, const sp<IMediaSource> &source, size_t trackId);
 
     ~Track();
 
@@ -228,7 +228,7 @@
 
     MPEG4Writer *mOwner;
     sp<MetaData> mMeta;
-    sp<MediaSource> mSource;
+    sp<IMediaSource> mSource;
     volatile bool mDone;
     volatile bool mPaused;
     volatile bool mResumed;
@@ -470,7 +470,7 @@
     return NULL;
 }
 
-status_t MPEG4Writer::addSource(const sp<MediaSource> &source) {
+status_t MPEG4Writer::addSource(const sp<IMediaSource> &source) {
     Mutex::Autolock l(mLock);
     if (mStarted) {
         ALOGE("Attempt to add source AFTER recording is started");
@@ -1436,7 +1436,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 MPEG4Writer::Track::Track(
-        MPEG4Writer *owner, const sp<MediaSource> &source, size_t trackId)
+        MPEG4Writer *owner, const sp<IMediaSource> &source, size_t trackId)
     : mOwner(owner),
       mMeta(source->getFormat()),
       mSource(source),
diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp
index e21fe6e..53319eb 100644
--- a/media/libstagefright/MediaExtractor.cpp
+++ b/media/libstagefright/MediaExtractor.cpp
@@ -17,6 +17,7 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "MediaExtractor"
 #include <utils/Log.h>
+#include <pwd.h>
 
 #include "include/AMRExtractor.h"
 #include "include/MP3Extractor.h"
@@ -33,15 +34,34 @@
 
 #include "matroska/MatroskaExtractor.h"
 
+#include <binder/IServiceManager.h>
+#include <binder/MemoryDealer.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/IMediaExtractorService.h>
+#include <cutils/properties.h>
 #include <utils/String8.h>
+#include <private/android_filesystem_config.h>
+
 
 namespace android {
 
+MediaExtractor::MediaExtractor():
+    mIsDrm(false) {
+    if (!LOG_NDEBUG) {
+        uid_t uid = getuid();
+        struct passwd *pw = getpwuid(uid);
+        ALOGI("extractor created in uid: %d (%s)", getuid(), pw->pw_name);
+    }
+
+}
+
+
 sp<MetaData> MediaExtractor::getMetaData() {
     return new MetaData;
 }
@@ -50,9 +70,91 @@
     return CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_PAUSE | CAN_SEEK;
 }
 
+
+
+class RemoteDataSource : public BnDataSource {
+public:
+    enum {
+        kBufferSize = 64 * 1024,
+    };
+
+    static sp<IDataSource> wrap(const sp<DataSource> &source);
+    virtual ~RemoteDataSource();
+
+    virtual sp<IMemory> getIMemory();
+    virtual ssize_t readAt(off64_t offset, size_t size);
+    virtual status_t getSize(off64_t* size);
+    virtual void close();
+
+private:
+    sp<IMemory> mMemory;
+    sp<DataSource> mSource;
+    RemoteDataSource(const sp<DataSource> &source);
+    DISALLOW_EVIL_CONSTRUCTORS(RemoteDataSource);
+};
+
+
+sp<IDataSource> RemoteDataSource::wrap(const sp<DataSource> &source) {
+    return new RemoteDataSource(source);
+}
+RemoteDataSource::RemoteDataSource(const sp<DataSource> &source) {
+    mSource = source;
+    sp<MemoryDealer> memoryDealer = new MemoryDealer(kBufferSize, "RemoteDataSource");
+    mMemory = memoryDealer->allocate(kBufferSize);
+    if (mMemory == NULL) {
+        ALOGE("Failed to allocate memory!");
+    }
+}
+RemoteDataSource::~RemoteDataSource() {
+    close();
+}
+sp<IMemory> RemoteDataSource::getIMemory() {
+    return mMemory;
+}
+ssize_t RemoteDataSource::readAt(off64_t offset, size_t size) {
+    ALOGV("readAt(%lld, %d)", offset, size);
+    return mSource->readAt(offset, mMemory->pointer(), size);
+}
+status_t RemoteDataSource::getSize(off64_t* size) {
+    return mSource->getSize(size);
+}
+void RemoteDataSource::close() {
+    mSource = NULL;
+}
+
 // static
-sp<MediaExtractor> MediaExtractor::Create(
+sp<IMediaExtractor> MediaExtractor::Create(
         const sp<DataSource> &source, const char *mime) {
+    ALOGV("MediaExtractor::Create %s", mime);
+
+    char value[PROPERTY_VALUE_MAX];
+    if (property_get("media.stagefright.extractremote", value, NULL)
+            && (!strcmp("0", value) || !strcasecmp("false", value))) {
+        // local extractor
+        ALOGW("creating media extractor in calling process");
+        return CreateFromService(source, mime);
+    } 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(RemoteDataSource::wrap(source), 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);
+    DataSource::RegisterDefaultSniffers();
+
     sp<AMessage> meta;
 
     String8 tmp;
diff --git a/media/libstagefright/MediaSource.cpp b/media/libstagefright/MediaSource.cpp
index 576471a..a17757a 100644
--- a/media/libstagefright/MediaSource.cpp
+++ b/media/libstagefright/MediaSource.cpp
@@ -22,56 +22,4 @@
 
 MediaSource::~MediaSource() {}
 
-////////////////////////////////////////////////////////////////////////////////
-
-MediaSource::ReadOptions::ReadOptions() {
-    reset();
-}
-
-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/libstagefright/MidiExtractor.cpp b/media/libstagefright/MidiExtractor.cpp
index f6b8c84..7525f57 100644
--- a/media/libstagefright/MidiExtractor.cpp
+++ b/media/libstagefright/MidiExtractor.cpp
@@ -281,7 +281,7 @@
     return mInitCheck == OK ? 1 : 0;
 }
 
-sp<MediaSource> MidiExtractor::getTrack(size_t index)
+sp<IMediaSource> MidiExtractor::getTrack(size_t index)
 {
     if (mInitCheck != OK || index > 0) {
         return NULL;
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index f67b80e..67d9921 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -285,7 +285,7 @@
         }
     }
 
-    sp<MediaSource> source = mImpl->getTrack(index);
+    sp<IMediaSource> source = mImpl->getTrack(index);
 
     CHECK_EQ((status_t)OK, source->start());
 
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 6938b3c..41fbf75 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -70,7 +70,7 @@
 const static uint32_t kMaxColorFormatSupported = 1000;
 
 #define FACTORY_CREATE_ENCODER(name) \
-static sp<MediaSource> Make##name(const sp<MediaSource> &source, const sp<MetaData> &meta) { \
+static sp<IMediaSource> Make##name(const sp<IMediaSource> &source, const sp<MetaData> &meta) { \
     return new name(source, meta); \
 }
 
@@ -78,12 +78,12 @@
 
 FACTORY_CREATE_ENCODER(AACEncoder)
 
-static sp<MediaSource> InstantiateSoftwareEncoder(
-        const char *name, const sp<MediaSource> &source,
+static sp<IMediaSource> InstantiateSoftwareEncoder(
+        const char *name, const sp<IMediaSource> &source,
         const sp<MetaData> &meta) {
     struct FactoryInfo {
         const char *name;
-        sp<MediaSource> (*CreateFunc)(const sp<MediaSource> &, const sp<MetaData> &);
+        sp<IMediaSource> (*CreateFunc)(const sp<IMediaSource> &, const sp<MetaData> &);
     };
 
     static const FactoryInfo kFactoryInfo[] = {
@@ -289,10 +289,10 @@
 }
 
 // static
-sp<MediaSource> OMXCodec::Create(
+sp<IMediaSource> OMXCodec::Create(
         const sp<IOMX> &omx,
         const sp<MetaData> &meta, bool createEncoder,
-        const sp<MediaSource> &source,
+        const sp<IMediaSource> &source,
         const char *matchComponentName,
         uint32_t flags,
         const sp<ANativeWindow> &nativeWindow) {
@@ -337,7 +337,7 @@
         }
 
         if (createEncoder) {
-            sp<MediaSource> softwareCodec =
+            sp<IMediaSource> softwareCodec =
                 InstantiateSoftwareEncoder(componentName, source, meta);
 
             if (softwareCodec != NULL) {
@@ -1426,7 +1426,7 @@
         bool isEncoder,
         const char *mime,
         const char *componentName,
-        const sp<MediaSource> &source,
+        const sp<IMediaSource> &source,
         const sp<ANativeWindow> &nativeWindow)
     : mOMX(omx),
       mOMXLivesLocally(omx->livesLocally(node, getpid())),
diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp
index c216b53..9162f80 100644
--- a/media/libstagefright/OggExtractor.cpp
+++ b/media/libstagefright/OggExtractor.cpp
@@ -1325,7 +1325,7 @@
     return mInitCheck != OK ? 0 : 1;
 }
 
-sp<MediaSource> OggExtractor::getTrack(size_t index) {
+sp<IMediaSource> OggExtractor::getTrack(size_t index) {
     if (index >= 1) {
         return NULL;
     }
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index 5eff50f..055b659 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -139,7 +139,7 @@
 static VideoFrame *extractVideoFrame(
         const char *componentName,
         const sp<MetaData> &trackMeta,
-        const sp<MediaSource> &source,
+        const sp<IMediaSource> &source,
         int64_t frameTimeUs,
         int seekMode) {
 
@@ -459,7 +459,7 @@
     sp<MetaData> trackMeta = mExtractor->getTrackMetaData(
             i, MediaExtractor::kIncludeExtensiveMetaData);
 
-    sp<MediaSource> source = mExtractor->getTrack(i);
+    sp<IMediaSource> source = mExtractor->getTrack(i);
 
     if (source.get() == NULL) {
         ALOGV("unable to instantiate video track.");
diff --git a/media/libstagefright/WAVExtractor.cpp b/media/libstagefright/WAVExtractor.cpp
index b30376d..bc6df79 100644
--- a/media/libstagefright/WAVExtractor.cpp
+++ b/media/libstagefright/WAVExtractor.cpp
@@ -116,7 +116,7 @@
     return mInitCheck == OK ? 1 : 0;
 }
 
-sp<MediaSource> WAVExtractor::getTrack(size_t index) {
+sp<IMediaSource> WAVExtractor::getTrack(size_t index) {
     if (mInitCheck != OK || index > 0) {
         return NULL;
     }
diff --git a/media/libstagefright/WVMExtractor.cpp b/media/libstagefright/WVMExtractor.cpp
index bc48272..d1b2f54 100644
--- a/media/libstagefright/WVMExtractor.cpp
+++ b/media/libstagefright/WVMExtractor.cpp
@@ -95,7 +95,7 @@
     return (mImpl != NULL) ? mImpl->countTracks() : 0;
 }
 
-sp<MediaSource> WVMExtractor::getTrack(size_t index) {
+sp<IMediaSource> WVMExtractor::getTrack(size_t index) {
     if (mImpl == NULL) {
         return NULL;
     }
diff --git a/media/libstagefright/codecs/aacenc/AACEncoder.cpp b/media/libstagefright/codecs/aacenc/AACEncoder.cpp
index bebb9dc..9e596ff 100644
--- a/media/libstagefright/codecs/aacenc/AACEncoder.cpp
+++ b/media/libstagefright/codecs/aacenc/AACEncoder.cpp
@@ -30,7 +30,7 @@
 
 namespace android {
 
-AACEncoder::AACEncoder(const sp<MediaSource> &source, const sp<MetaData> &meta)
+AACEncoder::AACEncoder(const sp<IMediaSource> &source, const sp<MetaData> &meta)
     : mSource(source),
       mMeta(meta),
       mStarted(false),
diff --git a/media/libstagefright/foundation/Android.mk b/media/libstagefright/foundation/Android.mk
index 7a7535c..e17534f 100644
--- a/media/libstagefright/foundation/Android.mk
+++ b/media/libstagefright/foundation/Android.mk
@@ -15,6 +15,8 @@
     AString.cpp                   \
     AStringUtils.cpp              \
     AWakeLock.cpp                 \
+    MediaBuffer.cpp               \
+    MetaData.cpp                  \
     ParsedMessage.cpp             \
     base64.cpp                    \
     hexdump.cpp
diff --git a/media/libstagefright/MediaBuffer.cpp b/media/libstagefright/foundation/MediaBuffer.cpp
similarity index 100%
rename from media/libstagefright/MediaBuffer.cpp
rename to media/libstagefright/foundation/MediaBuffer.cpp
diff --git a/media/libstagefright/MetaData.cpp b/media/libstagefright/foundation/MetaData.cpp
similarity index 85%
rename from media/libstagefright/MetaData.cpp
rename to media/libstagefright/foundation/MetaData.cpp
index 7a8bd98..b847eed 100644
--- a/media/libstagefright/MetaData.cpp
+++ b/media/libstagefright/foundation/MetaData.cpp
@@ -377,5 +377,57 @@
     }
 }
 
+status_t MetaData::writeToParcel(Parcel &parcel) {
+    size_t numItems = mItems.size();
+    parcel.writeUint32(uint32_t(numItems));
+    for (size_t i = 0; i < numItems; i++) {
+        int32_t key = mItems.keyAt(i);
+        const typed_data &item = mItems.valueAt(i);
+        uint32_t type;
+        const void *data;
+        size_t size;
+        item.getData(&type, &data, &size);
+        parcel.writeInt32(key);
+        parcel.writeUint32(type);
+        parcel.writeByteArray(size, (uint8_t*)data);
+    }
+    return OK;
+}
+
+status_t MetaData::updateFromParcel(const Parcel &parcel) {
+    uint32_t numItems;
+    if (parcel.readUint32(&numItems) == OK) {
+
+        for (size_t i = 0; i < numItems; i++) {
+            int32_t key;
+            uint32_t type;
+            uint32_t size;
+            status_t ret = parcel.readInt32(&key);
+            ret |= parcel.readUint32(&type);
+            ret |= parcel.readUint32(&size);
+            if (ret != OK) {
+                break;
+            }
+            // copy data directly from Parcel storage, then advance position
+            setData(key, type, parcel.readInplace(size), size);
+         }
+
+        return OK;
+    }
+    ALOGW("no metadata in parcel");
+    return UNKNOWN_ERROR;
+}
+
+
+/* static */
+sp<MetaData> MetaData::createFromParcel(const Parcel &parcel) {
+
+    sp<MetaData> meta = new MetaData();
+    meta->updateFromParcel(parcel);
+    return meta;
+}
+
+
+
 }  // namespace android
 
diff --git a/media/libstagefright/include/AACEncoder.h b/media/libstagefright/include/AACEncoder.h
index 52beb0e..462e905 100644
--- a/media/libstagefright/include/AACEncoder.h
+++ b/media/libstagefright/include/AACEncoder.h
@@ -27,9 +27,9 @@
 
 class MediaBufferGroup;
 
-class AACEncoder: public MediaSource {
+class AACEncoder: public BnMediaSource {
     public:
-        AACEncoder(const sp<MediaSource> &source, const sp<MetaData> &meta);
+        AACEncoder(const sp<IMediaSource> &source, const sp<MetaData> &meta);
 
         virtual status_t start(MetaData *params);
         virtual status_t stop();
@@ -42,7 +42,7 @@
         virtual ~AACEncoder();
 
     private:
-        sp<MediaSource>   mSource;
+        sp<IMediaSource>   mSource;
         sp<MetaData>      mMeta;
         bool              mStarted;
         MediaBufferGroup *mBufferGroup;
diff --git a/media/libstagefright/include/AACExtractor.h b/media/libstagefright/include/AACExtractor.h
index e98ca82..e231e62 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<MediaSource> getTrack(size_t index);
+    virtual sp<IMediaSource> 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 4a1c827..0770397 100644
--- a/media/libstagefright/include/AMRExtractor.h
+++ b/media/libstagefright/include/AMRExtractor.h
@@ -32,7 +32,7 @@
     AMRExtractor(const sp<DataSource> &source);
 
     virtual size_t countTracks();
-    virtual sp<MediaSource> getTrack(size_t index);
+    virtual sp<IMediaSource> getTrack(size_t index);
     virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
 
     virtual sp<MetaData> getMetaData();
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 32b4f47..1204ee8 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -23,6 +23,7 @@
 
 #include <media/AudioResamplerPublic.h>
 #include <media/MediaPlayerInterface.h>
+#include <media/IMediaExtractor.h>
 #include <media/stagefright/DataSource.h>
 #include <media/stagefright/OMXClient.h>
 #include <media/stagefright/TimeSource.h>
@@ -36,8 +37,6 @@
 struct ClockEstimator;
 class IDataSource;
 class MediaBuffer;
-struct MediaExtractor;
-struct MediaSource;
 struct NuCachedSource2;
 class IGraphicBufferProducer;
 
@@ -170,8 +169,8 @@
 
     sp<DataSource> mFileSource;
 
-    sp<MediaSource> mVideoTrack;
-    sp<MediaSource> mVideoSource;
+    sp<IMediaSource> mVideoTrack;
+    sp<IMediaSource> mVideoSource;
     sp<AwesomeRenderer> mVideoRenderer;
     bool mVideoRenderingStarted;
     bool mVideoRendererIsPreview;
@@ -179,9 +178,9 @@
     int32_t mStartGeneration;
 
     ssize_t mActiveAudioTrackIndex;
-    sp<MediaSource> mAudioTrack;
-    sp<MediaSource> mOmxSource;
-    sp<MediaSource> mAudioSource;
+    sp<IMediaSource> mAudioTrack;
+    sp<IMediaSource> mOmxSource;
+    sp<IMediaSource> mAudioSource;
     AudioPlayer *mAudioPlayer;
     AudioPlaybackRate mPlaybackSettings;
     int64_t mDurationUs;
@@ -253,7 +252,7 @@
     int32_t mSelectedTimedTextTrack;
 
     sp<WVMExtractor> mWVMExtractor;
-    sp<MediaExtractor> mExtractor;
+    sp<IMediaExtractor> mExtractor;
 
     status_t setDataSource_l(
             const sp<IMediaHTTPService> &httpService,
@@ -261,7 +260,7 @@
             const KeyedVector<String8, String8> *headers = NULL);
 
     status_t setDataSource_l(const sp<DataSource> &dataSource);
-    status_t setDataSource_l(const sp<MediaExtractor> &extractor);
+    status_t setDataSource_l(const sp<IMediaExtractor> &extractor);
     void reset_l();
     status_t seekTo_l(int64_t timeUs);
     status_t pause_l(bool at_eos = false);
@@ -271,14 +270,14 @@
 
     void cancelPlayerEvents(bool keepNotifications = false);
 
-    void setAudioSource(sp<MediaSource> source);
+    void setAudioSource(sp<IMediaSource> source);
     status_t initAudioDecoder();
 
 
-    void setVideoSource(sp<MediaSource> source);
+    void setVideoSource(sp<IMediaSource> source);
     status_t initVideoDecoder(uint32_t flags = 0);
 
-    void addTextSource_l(size_t trackIndex, const sp<MediaSource>& source);
+    void addTextSource_l(size_t trackIndex, const sp<IMediaSource>& source);
 
     void onStreamDone();
 
@@ -360,7 +359,7 @@
     status_t setVideoScalingMode_l(int32_t mode);
     status_t getTrackInfo(Parcel* reply) const;
 
-    status_t selectAudioTrack_l(const sp<MediaSource>& source, size_t trackIndex);
+    status_t selectAudioTrack_l(const sp<IMediaSource>& source, size_t trackIndex);
 
     // when select is true, the given track is selected.
     // otherwise, the given track is unselected.
diff --git a/media/libstagefright/include/DRMExtractor.h b/media/libstagefright/include/DRMExtractor.h
index b4e4afb..a035d8c 100644
--- a/media/libstagefright/include/DRMExtractor.h
+++ b/media/libstagefright/include/DRMExtractor.h
@@ -18,6 +18,7 @@
 
 #define DRM_EXTRACTOR_H_
 
+#include <media/IMediaSource.h>
 #include <media/stagefright/MediaExtractor.h>
 #include <drm/DrmManagerClient.h>
 
@@ -34,7 +35,7 @@
     DRMExtractor(const sp<DataSource> &source, const char *mime);
 
     virtual size_t countTracks();
-    virtual sp<MediaSource> getTrack(size_t index);
+    virtual sp<IMediaSource> getTrack(size_t index);
     virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
     virtual sp<MetaData> getMetaData();
 
@@ -44,7 +45,7 @@
 private:
     sp<DataSource> mDataSource;
 
-    sp<MediaExtractor> mOriginalExtractor;
+    sp<IMediaExtractor> mOriginalExtractor;
     sp<DecryptHandle> mDecryptHandle;
     DrmManagerClient* mDrmManagerClient;
 
diff --git a/media/libstagefright/include/FLACExtractor.h b/media/libstagefright/include/FLACExtractor.h
index ded91c2..a6e6c1d 100644
--- a/media/libstagefright/include/FLACExtractor.h
+++ b/media/libstagefright/include/FLACExtractor.h
@@ -32,7 +32,7 @@
     FLACExtractor(const sp<DataSource> &source);
 
     virtual size_t countTracks();
-    virtual sp<MediaSource> getTrack(size_t index);
+    virtual sp<IMediaSource> 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 c83d9e8..2fd04f2 100644
--- a/media/libstagefright/include/MP3Extractor.h
+++ b/media/libstagefright/include/MP3Extractor.h
@@ -34,10 +34,11 @@
     MP3Extractor(const sp<DataSource> &source, const sp<AMessage> &meta);
 
     virtual size_t countTracks();
-    virtual sp<MediaSource> getTrack(size_t index);
+    virtual sp<IMediaSource> getTrack(size_t index);
     virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
 
     virtual sp<MetaData> getMetaData();
+    virtual const char * name() { return "MP3Extractor"; }
 
 private:
     status_t mInitCheck;
diff --git a/media/libstagefright/include/MPEG2PSExtractor.h b/media/libstagefright/include/MPEG2PSExtractor.h
index 22cb02d..e815f0e 100644
--- a/media/libstagefright/include/MPEG2PSExtractor.h
+++ b/media/libstagefright/include/MPEG2PSExtractor.h
@@ -34,7 +34,7 @@
     MPEG2PSExtractor(const sp<DataSource> &source);
 
     virtual size_t countTracks();
-    virtual sp<MediaSource> getTrack(size_t index);
+    virtual sp<IMediaSource> 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 8eb8f6c..9907572 100644
--- a/media/libstagefright/include/MPEG2TSExtractor.h
+++ b/media/libstagefright/include/MPEG2TSExtractor.h
@@ -38,7 +38,7 @@
     MPEG2TSExtractor(const sp<DataSource> &source);
 
     virtual size_t countTracks();
-    virtual sp<MediaSource> getTrack(size_t index);
+    virtual sp<IMediaSource> 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 3067c3d..cff976d 100644
--- a/media/libstagefright/include/MPEG4Extractor.h
+++ b/media/libstagefright/include/MPEG4Extractor.h
@@ -53,7 +53,7 @@
     MPEG4Extractor(const sp<DataSource> &source);
 
     virtual size_t countTracks();
-    virtual sp<MediaSource> getTrack(size_t index);
+    virtual sp<IMediaSource> 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 9a2abc0..333277b 100644
--- a/media/libstagefright/include/MidiExtractor.h
+++ b/media/libstagefright/include/MidiExtractor.h
@@ -56,7 +56,7 @@
     MidiExtractor(const sp<DataSource> &source);
 
     virtual size_t countTracks();
-    virtual sp<MediaSource> getTrack(size_t index);
+    virtual sp<IMediaSource> 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 c647cbb..592c264 100644
--- a/media/libstagefright/include/OggExtractor.h
+++ b/media/libstagefright/include/OggExtractor.h
@@ -34,10 +34,11 @@
     OggExtractor(const sp<DataSource> &source);
 
     virtual size_t countTracks();
-    virtual sp<MediaSource> getTrack(size_t index);
+    virtual sp<IMediaSource> getTrack(size_t index);
     virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
 
     virtual sp<MetaData> getMetaData();
+    virtual const char * name() { return "OggExtractor"; }
 
 protected:
     virtual ~OggExtractor();
diff --git a/media/libstagefright/include/StagefrightMetadataRetriever.h b/media/libstagefright/include/StagefrightMetadataRetriever.h
index fd739d0..6684e1f 100644
--- a/media/libstagefright/include/StagefrightMetadataRetriever.h
+++ b/media/libstagefright/include/StagefrightMetadataRetriever.h
@@ -18,6 +18,7 @@
 
 #define STAGEFRIGHT_METADATA_RETRIEVER_H_
 
+#include <media/IMediaExtractor.h>
 #include <media/MediaMetadataRetrieverInterface.h>
 
 #include <media/stagefright/OMXClient.h>
@@ -47,7 +48,7 @@
 private:
     OMXClient mClient;
     sp<DataSource> mSource;
-    sp<MediaExtractor> mExtractor;
+    sp<IMediaExtractor> mExtractor;
 
     bool mParsedMetaData;
     KeyedVector<int, String8> mMetaData;
diff --git a/media/libstagefright/include/WAVExtractor.h b/media/libstagefright/include/WAVExtractor.h
index c567ccd..91ee870 100644
--- a/media/libstagefright/include/WAVExtractor.h
+++ b/media/libstagefright/include/WAVExtractor.h
@@ -33,10 +33,11 @@
     WAVExtractor(const sp<DataSource> &source);
 
     virtual size_t countTracks();
-    virtual sp<MediaSource> getTrack(size_t index);
+    virtual sp<IMediaSource> getTrack(size_t index);
     virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
 
     virtual sp<MetaData> getMetaData();
+    virtual const char * name() { return "WAVExtractor"; }
 
 protected:
     virtual ~WAVExtractor();
diff --git a/media/libstagefright/include/WVMExtractor.h b/media/libstagefright/include/WVMExtractor.h
index ab7e8b8..5b91072 100644
--- a/media/libstagefright/include/WVMExtractor.h
+++ b/media/libstagefright/include/WVMExtractor.h
@@ -46,7 +46,7 @@
     WVMExtractor(const sp<DataSource> &source);
 
     virtual size_t countTracks();
-    virtual sp<MediaSource> getTrack(size_t index);
+    virtual sp<IMediaSource> getTrack(size_t index);
     virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
     virtual sp<MetaData> getMetaData();
     virtual void setUID(uid_t uid);
diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp
index ecc2573..a00ad4b 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.cpp
+++ b/media/libstagefright/matroska/MatroskaExtractor.cpp
@@ -761,7 +761,7 @@
     return mTracks.size();
 }
 
-sp<MediaSource> MatroskaExtractor::getTrack(size_t index) {
+sp<IMediaSource> 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 db36bf8..120ef82 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.h
+++ b/media/libstagefright/matroska/MatroskaExtractor.h
@@ -37,7 +37,7 @@
 
     virtual size_t countTracks();
 
-    virtual sp<MediaSource> getTrack(size_t index);
+    virtual sp<IMediaSource> 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 0f18fac..078a5f0 100644
--- a/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
@@ -125,7 +125,7 @@
     return mTracks.size();
 }
 
-sp<MediaSource> MPEG2PSExtractor::getTrack(size_t index) {
+sp<IMediaSource> 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 cbe9673..0b456c3 100644
--- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
@@ -120,7 +120,7 @@
     return mSourceImpls.size();
 }
 
-sp<MediaSource> MPEG2TSExtractor::getTrack(size_t index) {
+sp<IMediaSource> 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 644b6ed..5159de3 100644
--- a/media/libstagefright/omx/tests/OMXHarness.cpp
+++ b/media/libstagefright/omx/tests/OMXHarness.cpp
@@ -244,7 +244,7 @@
     NodeReaper &operator=(const NodeReaper &);
 };
 
-static sp<MediaExtractor> CreateExtractorFromURI(const char *uri) {
+static sp<IMediaExtractor> CreateExtractorFromURI(const char *uri) {
     sp<DataSource> source =
         DataSource::CreateFromURI(NULL /* httpService */, uri);
 
@@ -492,14 +492,14 @@
     return NULL;
 }
 
-static sp<MediaSource> CreateSourceForMime(const char *mime) {
+static sp<IMediaSource> CreateSourceForMime(const char *mime) {
     const char *url = GetURLForMime(mime);
 
     if (url == NULL) {
         return NULL;
     }
 
-    sp<MediaExtractor> extractor = CreateExtractorFromURI(url);
+    sp<IMediaExtractor> extractor = CreateExtractorFromURI(url);
 
     if (extractor == NULL) {
         return NULL;
@@ -559,7 +559,7 @@
         return OK;
     }
 
-    sp<MediaSource> source = CreateSourceForMime(mime);
+    sp<IMediaSource> source = CreateSourceForMime(mime);
 
     if (source == NULL) {
         printf("  * Unable to open test content for type '%s', "
@@ -569,14 +569,14 @@
         return OK;
     }
 
-    sp<MediaSource> seekSource = CreateSourceForMime(mime);
+    sp<IMediaSource> seekSource = CreateSourceForMime(mime);
     if (source == NULL || seekSource == NULL) {
         return UNKNOWN_ERROR;
     }
 
     CHECK_EQ(seekSource->start(), (status_t)OK);
 
-    sp<MediaSource> codec = OMXCodec::Create(
+    sp<IMediaSource> codec = OMXCodec::Create(
             mOMX, source->getFormat(), false /* createEncoder */,
             source, componentName);
 
diff --git a/media/libstagefright/rtsp/ARTPWriter.cpp b/media/libstagefright/rtsp/ARTPWriter.cpp
index 56c4aa6..1f6b6f7 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<MediaSource> &source) {
+status_t ARTPWriter::addSource(const sp<IMediaSource> &source) {
     mSource = source;
     return OK;
 }
diff --git a/media/libstagefright/rtsp/ARTPWriter.h b/media/libstagefright/rtsp/ARTPWriter.h
index be8bc13..62abd0a 100644
--- a/media/libstagefright/rtsp/ARTPWriter.h
+++ b/media/libstagefright/rtsp/ARTPWriter.h
@@ -37,7 +37,7 @@
 struct ARTPWriter : public MediaWriter {
     ARTPWriter(int fd);
 
-    virtual status_t addSource(const sp<MediaSource> &source);
+    virtual status_t addSource(const sp<IMediaSource> &source);
     virtual bool reachedEOS();
     virtual status_t start(MetaData *params);
     virtual status_t stop();
@@ -72,7 +72,7 @@
     int mRTCPFd;
 #endif
 
-    sp<MediaSource> mSource;
+    sp<IMediaSource> mSource;
     sp<ALooper> mLooper;
     sp<AHandlerReflector<ARTPWriter> > mReflector;
 
diff --git a/media/libstagefright/timedtext/TimedText3GPPSource.cpp b/media/libstagefright/timedtext/TimedText3GPPSource.cpp
index 4854121..0c8fb79 100644
--- a/media/libstagefright/timedtext/TimedText3GPPSource.cpp
+++ b/media/libstagefright/timedtext/TimedText3GPPSource.cpp
@@ -31,7 +31,7 @@
 
 namespace android {
 
-TimedText3GPPSource::TimedText3GPPSource(const sp<MediaSource>& mediaSource)
+TimedText3GPPSource::TimedText3GPPSource(const sp<IMediaSource>& mediaSource)
     : mSource(mediaSource) {
 }
 
diff --git a/media/libstagefright/timedtext/TimedText3GPPSource.h b/media/libstagefright/timedtext/TimedText3GPPSource.h
index 4170940..fdc79ca 100644
--- a/media/libstagefright/timedtext/TimedText3GPPSource.h
+++ b/media/libstagefright/timedtext/TimedText3GPPSource.h
@@ -29,7 +29,7 @@
 
 class TimedText3GPPSource : public TimedTextSource {
 public:
-    TimedText3GPPSource(const sp<MediaSource>& mediaSource);
+    TimedText3GPPSource(const sp<IMediaSource>& mediaSource);
     virtual status_t start() { return mSource->start(); }
     virtual status_t stop() { return mSource->stop(); }
     virtual status_t read(
@@ -44,7 +44,7 @@
     virtual ~TimedText3GPPSource();
 
 private:
-    sp<MediaSource> mSource;
+    sp<IMediaSource> mSource;
 
     status_t extractAndAppendLocalDescriptions(
             int64_t timeUs, const MediaBuffer *textBuffer, Parcel *parcel);
diff --git a/media/libstagefright/timedtext/TimedTextDriver.cpp b/media/libstagefright/timedtext/TimedTextDriver.cpp
index 55a9803..fd0eebb 100644
--- a/media/libstagefright/timedtext/TimedTextDriver.cpp
+++ b/media/libstagefright/timedtext/TimedTextDriver.cpp
@@ -188,7 +188,7 @@
 }
 
 status_t TimedTextDriver::addInBandTextSource(
-        size_t trackIndex, const sp<MediaSource>& mediaSource) {
+        size_t trackIndex, const sp<IMediaSource>& mediaSource) {
     sp<TimedTextSource> source =
             TimedTextSource::CreateTimedTextSource(mediaSource);
     if (source == NULL) {
diff --git a/media/libstagefright/timedtext/TimedTextSource.cpp b/media/libstagefright/timedtext/TimedTextSource.cpp
index 953f7b5..e5aa382 100644
--- a/media/libstagefright/timedtext/TimedTextSource.cpp
+++ b/media/libstagefright/timedtext/TimedTextSource.cpp
@@ -33,7 +33,7 @@
 
 // static
 sp<TimedTextSource> TimedTextSource::CreateTimedTextSource(
-        const sp<MediaSource>& mediaSource) {
+        const sp<IMediaSource>& mediaSource) {
     const char *mime;
     CHECK(mediaSource->getFormat()->findCString(kKeyMIMEType, &mime));
     if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) == 0) {
diff --git a/media/libstagefright/timedtext/TimedTextSource.h b/media/libstagefright/timedtext/TimedTextSource.h
index 8c1c1cd..9946721 100644
--- a/media/libstagefright/timedtext/TimedTextSource.h
+++ b/media/libstagefright/timedtext/TimedTextSource.h
@@ -35,7 +35,7 @@
       OUT_OF_BAND_FILE_SMI = 2,
   };
   static sp<TimedTextSource> CreateTimedTextSource(
-      const sp<MediaSource>& source);
+      const sp<IMediaSource>& source);
   static sp<TimedTextSource> CreateTimedTextSource(
       const sp<DataSource>& source, FileType filetype);
   TimedTextSource() {}
diff --git a/media/libstagefright/webm/WebmFrameThread.cpp b/media/libstagefright/webm/WebmFrameThread.cpp
index a4b8a42..7eb4745 100644
--- a/media/libstagefright/webm/WebmFrameThread.cpp
+++ b/media/libstagefright/webm/WebmFrameThread.cpp
@@ -246,7 +246,7 @@
 }
 
 WebmFrameMediaSourceThread::WebmFrameMediaSourceThread(
-        const sp<MediaSource>& source,
+        const sp<IMediaSource>& 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 d65d9b7..528984f 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<MediaSource>& source,
+            const sp<IMediaSource>& source,
             int type,
             LinkedBlockingQueue<const sp<WebmFrame> >& sink,
             uint64_t timeCodeScale,
@@ -142,7 +142,7 @@
     }
 
 private:
-    const sp<MediaSource> mSource;
+    const sp<IMediaSource> mSource;
     const uint64_t mTimeCodeScale;
     uint64_t mStartTimeUs;
 
diff --git a/media/libstagefright/webm/WebmWriter.cpp b/media/libstagefright/webm/WebmWriter.cpp
index 737f144..7f6ba01 100644
--- a/media/libstagefright/webm/WebmWriter.cpp
+++ b/media/libstagefright/webm/WebmWriter.cpp
@@ -328,7 +328,7 @@
     return err;
 }
 
-status_t WebmWriter::addSource(const sp<MediaSource> &source) {
+status_t WebmWriter::addSource(const sp<IMediaSource> &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 4ad770e..4a7f506 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<MediaSource> &source);
+    virtual status_t addSource(const sp<IMediaSource> &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<MediaSource> mSource;
+        sp<IMediaSource> mSource;
         sp<WebmElement> mTrackEntry;
         sp<WebmFrameSourceThread> mThread;
         LinkedBlockingQueue<const sp<WebmFrame> > mSink;