Squashed commit of the following:

commit 5bb012f0065f7ffaaeb4f569d71f0e3a8d6b19c3
Author: Andreas Huber <andih@google.com>
Date:   Fri Aug 14 10:40:08 2009 -0700

    An attempt at fixing export using the qcom encoders. More quirks.

commit 0690e76bfa48118a68287ccf1bbfa82febaa620c
Author: Andreas Huber <andih@google.com>
Date:   Fri Aug 14 09:08:28 2009 -0700

    Callbacks are now dispatched from a separate thread in OMX.

commit c6571a039526df29b6343f9a1971dbc019088c61
Author: Andreas Huber <andih@google.com>
Date:   Thu Aug 13 15:42:25 2009 -0700

    Massive API changes throughout stagefright, smart pointers everywhere.

commit 900612af6a0555664d9ba195112cd859491265f4
Author: Andreas Huber <andih@google.com>
Date:   Thu Aug 13 13:33:12 2009 -0700

    OMXCodecs now properly shutdown.

commit 96732f05e1b0603dcd1b11f16a23512592eeb4f5
Author: Andreas Huber <andih@google.com>
Date:   Thu Aug 13 12:04:04 2009 -0700

    More work on JPEG decoding using the hardware OMX component.

commit 63839a073ac393e3a130434ba467969053b694ad
Author: Andreas Huber <andih@google.com>
Date:   Wed Aug 12 13:13:31 2009 -0700

    An attempt to drive the JPEG decoder OMX node.

commit 3ac2fe5ab2926eda81b2123610b2434c645294ff
Author: Andreas Huber <andih@google.com>
Date:   Tue Aug 11 16:38:21 2009 -0700

    Renamed StateMachine to OMXCodec and put it in its proper place.

commit 247da75a96bf8881956413023dd49a84d5b4f5b2
Author: Andreas Huber <andih@google.com>
Date:   Tue Aug 11 16:06:19 2009 -0700

    Statemachine is now a full-fledged MediaSource.

commit 045244f6771fa0b9b329495c953afda900a84b71
Author: Andreas Huber <andih@google.com>
Date:   Fri Aug 7 09:16:54 2009 -0700

    Properly setup the input format when exporting to AMR audio.

commit 271b984cb32c5cd9e46e3f90ae121f334e4b8da9
Author: Andreas Huber <andih@google.com>
Date:   Thu Aug 6 09:59:38 2009 -0700

    Added some code to test audio encoding to the OMX harness.

commit 79af4748e4af33bd66d3fbac606e332a69741cf4
Author: Andreas Huber <andih@google.com>
Date:   Wed Aug 5 14:36:22 2009 -0700

    Merge the old OMXDecoder and the new, shiny, StateMachine code.

commit 91cf5dd77a8762bc10a0b2ffce35e3bbeb262231
Author: Andreas Huber <andih@google.com>
Date:   Tue Aug 4 17:41:43 2009 -0700

    A new harness to test OMX node compliance (and quirks).
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index 7e5ff61..58a74c7 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -56,6 +56,14 @@
             node_id node, OMX_INDEXTYPE index,
             const void *params, size_t size) = 0;
 
+    virtual status_t get_config(
+            node_id node, OMX_INDEXTYPE index,
+            void *params, size_t size) = 0;
+
+    virtual status_t set_config(
+            node_id node, OMX_INDEXTYPE index,
+            const void *params, size_t size) = 0;
+
     virtual status_t use_buffer(
             node_id node, OMX_U32 port_index, const sp<IMemory> &params,
             buffer_id *buffer) = 0;
@@ -82,6 +90,11 @@
             OMX_U32 range_offset, OMX_U32 range_length,
             OMX_U32 flags, OMX_TICKS timestamp) = 0;
 
+    virtual status_t get_extension_index(
+            node_id node,
+            const char *parameter_name,
+            OMX_INDEXTYPE *index) = 0;
+
     virtual sp<IOMXRenderer> createRenderer(
             const sp<ISurface> &surface,
             const char *componentName,
@@ -114,10 +127,11 @@
         QUIT_OBSERVER,
     } type;
 
+    IOMX::node_id node;
+
     union {
         // if type == EVENT
         struct {
-            IOMX::node_id node;
             OMX_EVENTTYPE event;
             OMX_U32 data1;
             OMX_U32 data2;
@@ -126,13 +140,11 @@
         // if type == EMPTY_BUFFER_DONE || type == FILL_BUFFER
         //    || type == INITIAL_FILL_BUFFER
         struct {
-            IOMX::node_id node;
             IOMX::buffer_id buffer;
         } buffer_data;
 
         // if type == EMPTY_BUFFER || type == FILL_BUFFER_DONE
         struct {
-            IOMX::node_id node;
             IOMX::buffer_id buffer;
             OMX_U32 range_offset;
             OMX_U32 range_length;
@@ -143,7 +155,6 @@
 
         // if type == SEND_COMMAND
         struct {
-            IOMX::node_id node;
             OMX_COMMANDTYPE cmd;
             OMX_S32 param;
         } send_command_data;
diff --git a/include/media/stagefright/AudioPlayer.h b/include/media/stagefright/AudioPlayer.h
index 0f2e528..960eda3 100644
--- a/include/media/stagefright/AudioPlayer.h
+++ b/include/media/stagefright/AudioPlayer.h
@@ -31,10 +31,10 @@
 class AudioPlayer : public TimeSource {
 public:
     AudioPlayer(const sp<MediaPlayerBase::AudioSink> &audioSink);
-    ~AudioPlayer();
+    virtual ~AudioPlayer();
 
     // Caller retains ownership of "source".
-    void setSource(MediaSource *source);
+    void setSource(const sp<MediaSource> &source);
 
     // Return time in us.
     virtual int64_t getRealTimeUs();
@@ -56,7 +56,7 @@
     status_t seekTo(int64_t time_us);
 
 private:
-    MediaSource *mSource;
+    sp<MediaSource> mSource;
     AudioTrack *mAudioTrack;
 
     MediaBuffer *mInputBuffer;
diff --git a/include/media/stagefright/CachingDataSource.h b/include/media/stagefright/CachingDataSource.h
index e275cb4..e35e19e 100644
--- a/include/media/stagefright/CachingDataSource.h
+++ b/include/media/stagefright/CachingDataSource.h
@@ -26,14 +26,16 @@
 
 class CachingDataSource : public DataSource {
 public:
-    // Assumes ownership of "source".
-    CachingDataSource(DataSource *source, size_t pageSize, int numPages);
-    virtual ~CachingDataSource();
+    CachingDataSource(
+            const sp<DataSource> &source, size_t pageSize, int numPages);
 
     status_t InitCheck() const;
 
     virtual ssize_t read_at(off_t offset, void *data, size_t size);
 
+protected:
+    virtual ~CachingDataSource();
+
 private:
     struct Page {
         Page *mPrev, *mNext;
@@ -42,7 +44,7 @@
         void *mData;
     };
 
-    DataSource *mSource;
+    sp<DataSource> mSource;
     void *mData;
     size_t mPageSize;
     Page *mFirst, *mLast;
diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h
index 31eea27..f46f0af 100644
--- a/include/media/stagefright/DataSource.h
+++ b/include/media/stagefright/DataSource.h
@@ -22,19 +22,22 @@
 
 #include <utils/Errors.h>
 #include <utils/List.h>
+#include <utils/RefBase.h>
 #include <utils/threads.h>
 
 namespace android {
 
 class String8;
 
-class DataSource {
+class DataSource : public RefBase {
 public:
     DataSource() {}
-    virtual ~DataSource() {}
 
     virtual ssize_t read_at(off_t offset, void *data, size_t size) = 0;
 
+    // Convenience methods:
+    bool getUInt16(off_t offset, uint16_t *x);
+
     // May return ERROR_UNSUPPORTED.
     virtual status_t getSize(off_t *size);
 
@@ -43,11 +46,14 @@
     bool sniff(String8 *mimeType, float *confidence);
 
     typedef bool (*SnifferFunc)(
-            DataSource *source, String8 *mimeType, float *confidence);
+            const sp<DataSource> &source, String8 *mimeType, float *confidence);
 
     static void RegisterSniffer(SnifferFunc func);
     static void RegisterDefaultSniffers();
 
+protected:
+    virtual ~DataSource() {}
+
 private:
     static Mutex gSnifferMutex;
     static List<SnifferFunc> gSniffers;
diff --git a/include/media/stagefright/MP3Extractor.h b/include/media/stagefright/MP3Extractor.h
index 09cfb70..4e1f3c3 100644
--- a/include/media/stagefright/MP3Extractor.h
+++ b/include/media/stagefright/MP3Extractor.h
@@ -28,16 +28,17 @@
 class MP3Extractor : public MediaExtractor {
 public:
     // Extractor assumes ownership of "source".
-    MP3Extractor(DataSource *source);
+    MP3Extractor(const sp<DataSource> &source);
 
-    ~MP3Extractor();
+    size_t countTracks();
+    sp<MediaSource> getTrack(size_t index);
+    sp<MetaData> getTrackMetaData(size_t index);
 
-    status_t countTracks(int *num_tracks);
-    status_t getTrack(int index, MediaSource **source);
-    sp<MetaData> getTrackMetaData(int index);
+protected:
+    virtual ~MP3Extractor();
 
 private:
-    DataSource *mDataSource;
+    sp<DataSource> mDataSource;
     off_t mFirstFramePos;
     sp<MetaData> mMeta;
     uint32_t mFixedHeader;
@@ -46,7 +47,8 @@
     MP3Extractor &operator=(const MP3Extractor &);
 };
 
-bool SniffMP3(DataSource *source, String8 *mimeType, float *confidence);
+bool SniffMP3(
+        const sp<DataSource> &source, String8 *mimeType, float *confidence);
 
 }  // namespace android
 
diff --git a/include/media/stagefright/MPEG4Extractor.h b/include/media/stagefright/MPEG4Extractor.h
index 51a7e82..932e30f 100644
--- a/include/media/stagefright/MPEG4Extractor.h
+++ b/include/media/stagefright/MPEG4Extractor.h
@@ -29,22 +29,24 @@
 class MPEG4Extractor : public MediaExtractor {
 public:
     // Extractor assumes ownership of "source".
-    MPEG4Extractor(DataSource *source);
-    ~MPEG4Extractor();
+    MPEG4Extractor(const sp<DataSource> &source);
 
-    status_t countTracks(int *num_tracks);
-    status_t getTrack(int index, MediaSource **source);
-    sp<MetaData> getTrackMetaData(int index);
+    size_t countTracks();
+    sp<MediaSource> getTrack(size_t index);
+    sp<MetaData> getTrackMetaData(size_t index);
+
+protected:
+    virtual ~MPEG4Extractor();
 
 private:
     struct Track {
         Track *next;
         sp<MetaData> meta;
         uint32_t timescale;
-        SampleTable *sampleTable;
+        sp<SampleTable> sampleTable;
     };
 
-    DataSource *mDataSource;
+    sp<DataSource> mDataSource;
     bool mHaveMetadata;
 
     Track *mFirstTrack, *mLastTrack;
@@ -58,7 +60,8 @@
     MPEG4Extractor &operator=(const MPEG4Extractor &);
 };
 
-bool SniffMPEG4(DataSource *source, String8 *mimeType, float *confidence);
+bool SniffMPEG4(
+        const sp<DataSource> &source, String8 *mimeType, float *confidence);
 
 }  // namespace android
 
diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h
index 40d6127..5147de9 100644
--- a/include/media/stagefright/MPEG4Writer.h
+++ b/include/media/stagefright/MPEG4Writer.h
@@ -30,13 +30,12 @@
 class MediaSource;
 class MetaData;
 
-class MPEG4Writer {
+class MPEG4Writer : public RefBase {
 public:
     MPEG4Writer(const char *filename);
-    ~MPEG4Writer();
 
     // Caller retains ownership of both meta and source.
-    void addSource(const sp<MetaData> &meta, MediaSource *source);
+    void addSource(const sp<MetaData> &meta, const sp<MediaSource> &source);
     void start();
     void stop();
 
@@ -50,6 +49,9 @@
     void write(const void *data, size_t size);
     void endBox();
 
+protected:
+    virtual ~MPEG4Writer();
+
 private:
     class Track;
 
diff --git a/include/media/stagefright/MediaBuffer.h b/include/media/stagefright/MediaBuffer.h
index c72ed66..339e6fb 100644
--- a/include/media/stagefright/MediaBuffer.h
+++ b/include/media/stagefright/MediaBuffer.h
@@ -75,6 +75,8 @@
     // MetaData.
     MediaBuffer *clone();
 
+    int refcount() const;
+
 protected:
     virtual ~MediaBuffer();
 
@@ -102,8 +104,6 @@
     void setNextBuffer(MediaBuffer *buffer);
     MediaBuffer *nextBuffer();
 
-    int refcount() const;
-
     MediaBuffer(const MediaBuffer &);
     MediaBuffer &operator=(const MediaBuffer &);
 };
diff --git a/include/media/stagefright/MediaDebug.h b/include/media/stagefright/MediaDebug.h
new file mode 100644
index 0000000..83acd77
--- /dev/null
+++ b/include/media/stagefright/MediaDebug.h
@@ -0,0 +1,18 @@
+#ifndef MEDIA_DEBUG_H_
+
+#define MEDIA_DEBUG_H_
+
+#define LITERAL_TO_STRING_INTERNAL(x)    #x
+#define LITERAL_TO_STRING(x) LITERAL_TO_STRING_INTERNAL(x)
+
+#define CHECK_EQ(x,y)                                                   \
+    LOG_ALWAYS_FATAL_IF(                                                \
+            (x) != (y),                                                 \
+            __FILE__ ":" LITERAL_TO_STRING(__LINE__) " " #x " != " #y)
+
+#define CHECK(x)                                                        \
+    LOG_ALWAYS_FATAL_IF(                                                \
+            !(x),                                                       \
+            __FILE__ ":" LITERAL_TO_STRING(__LINE__) " " #x)
+
+#endif  // MEDIA_DEBUG_H_
diff --git a/include/media/stagefright/MediaExtractor.h b/include/media/stagefright/MediaExtractor.h
index 38f8e5b..67e45bd 100644
--- a/include/media/stagefright/MediaExtractor.h
+++ b/include/media/stagefright/MediaExtractor.h
@@ -26,18 +26,18 @@
 class MediaSource;
 class MetaData;
 
-class MediaExtractor {
+class MediaExtractor : public RefBase {
 public:
-    static MediaExtractor *Create(DataSource *source, const char *mime = NULL);
+    static sp<MediaExtractor> Create(
+            const sp<DataSource> &source, const char *mime = NULL);
 
-    virtual ~MediaExtractor() {}
-
-    virtual status_t countTracks(int *num_tracks) = 0;
-    virtual status_t getTrack(int index, MediaSource **source) = 0;
-    virtual sp<MetaData> getTrackMetaData(int index) = 0;
+    virtual size_t countTracks() = 0;
+    virtual sp<MediaSource> getTrack(size_t index) = 0;
+    virtual sp<MetaData> getTrackMetaData(size_t index) = 0;
 
 protected:
     MediaExtractor() {}
+    virtual ~MediaExtractor() {}
 
 private:
     MediaExtractor(const MediaExtractor &);
diff --git a/include/media/stagefright/MediaPlayerImpl.h b/include/media/stagefright/MediaPlayerImpl.h
index e96e5e8..53a2088 100644
--- a/include/media/stagefright/MediaPlayerImpl.h
+++ b/include/media/stagefright/MediaPlayerImpl.h
@@ -35,7 +35,6 @@
 class MediaSource;
 class MemoryHeapPmem;
 class MetaData;
-class OMXDecoder;
 class Surface;
 class TimeSource;
 
@@ -71,16 +70,16 @@
 
     OMXClient mClient;
 
-    MediaExtractor *mExtractor;
+    sp<MediaExtractor> mExtractor;
 
     TimeSource *mTimeSource;
 
-    MediaSource *mAudioSource;
-    OMXDecoder *mAudioDecoder;
+    sp<MediaSource> mAudioSource;
+    sp<MediaSource> mAudioDecoder;
     AudioPlayer *mAudioPlayer;
 
-    MediaSource *mVideoSource;
-    MediaSource *mVideoDecoder;
+    sp<MediaSource> mVideoSource;
+    sp<MediaSource> mVideoDecoder;
     int32_t mVideoWidth, mVideoHeight;
     int64_t mVideoPosition;
 
@@ -103,16 +102,13 @@
     bool mSeeking;
     int64_t mSeekTimeUs;
 
-    size_t mFrameSize;
-    bool mUseSoftwareColorConversion;
-
     void init();
 
     static void *VideoWrapper(void *me);
     void videoEntry();
 
-    void setAudioSource(MediaSource *source);
-    void setVideoSource(MediaSource *source);
+    void setAudioSource(const sp<MediaSource> &source);
+    void setVideoSource(const sp<MediaSource> &source);
 
     MediaSource *makeShoutcastSource(const char *path);
 
diff --git a/include/media/stagefright/MediaSource.h b/include/media/stagefright/MediaSource.h
index eb07f68..d1fa114 100644
--- a/include/media/stagefright/MediaSource.h
+++ b/include/media/stagefright/MediaSource.h
@@ -27,9 +27,8 @@
 class MediaBuffer;
 class MetaData;
 
-struct MediaSource {
+struct MediaSource : public RefBase {
     MediaSource();
-    virtual ~MediaSource();
 
     // To be called before any other methods on this object, except
     // getFormat().
@@ -81,6 +80,9 @@
         int64_t mLatenessUs;
     };
 
+protected:
+    virtual ~MediaSource();
+
 private:
     MediaSource(const MediaSource &);
     MediaSource &operator=(const MediaSource &);
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
new file mode 100644
index 0000000..d4ae349
--- /dev/null
+++ b/include/media/stagefright/OMXCodec.h
@@ -0,0 +1,190 @@
+/*
+ * 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.
+ */
+
+#ifndef OMX_CODEC_H_
+
+#define OMX_CODEC_H_
+
+#include <media/IOMX.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaSource.h>
+#include <utils/threads.h>
+
+namespace android {
+
+class MemoryDealer;
+struct OMXCodecObserver;
+
+struct OMXCodec : public MediaSource,
+                  public MediaBufferObserver {
+    static sp<OMXCodec> Create(
+            const sp<IOMX> &omx,
+            const sp<MetaData> &meta, bool createEncoder,
+            const sp<MediaSource> &source);
+
+    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);
+
+    void on_message(const omx_message &msg);
+
+    // from MediaBufferObserver
+    virtual void signalBufferReturned(MediaBuffer *buffer);
+
+protected:
+    virtual ~OMXCodec();
+
+private:
+    enum State {
+        DEAD,
+        LOADED,
+        LOADED_TO_IDLE,
+        IDLE_TO_EXECUTING,
+        EXECUTING,
+        EXECUTING_TO_IDLE,
+        IDLE_TO_LOADED,
+        RECONFIGURING,
+        ERROR
+    };
+
+    enum {
+        kPortIndexInput  = 0,
+        kPortIndexOutput = 1
+    };
+
+    enum PortStatus {
+        ENABLED,
+        DISABLING,
+        DISABLED,
+        ENABLING,
+        SHUTTING_DOWN,
+    };
+
+    enum Quirks {
+        kNeedsFlushBeforeDisable             = 1,
+        kWantsRawNALFrames                   = 2,
+        kRequiresLoadedToIdleAfterAllocation = 4,
+        kRequiresAllocateBufferOnInputPorts  = 8,
+    };
+
+    struct BufferInfo {
+        IOMX::buffer_id mBuffer;
+        bool mOwnedByComponent;
+        sp<IMemory> mMem;
+        MediaBuffer *mMediaBuffer;
+    };
+
+    struct CodecSpecificData {
+        size_t mSize;
+        uint8_t mData[1];
+    };
+
+    sp<IOMX> mOMX;
+    IOMX::node_id mNode;
+    sp<OMXCodecObserver> mObserver;
+    uint32_t mQuirks;
+    bool mIsEncoder;
+    char *mMIME;
+    char *mComponentName;
+    sp<MetaData> mOutputFormat;
+    sp<MediaSource> mSource;
+    Vector<CodecSpecificData *> mCodecSpecificData;
+    size_t mCodecSpecificDataIndex;
+
+    sp<MemoryDealer> mDealer;
+
+    State mState;
+    Vector<BufferInfo> mPortBuffers[2];
+    PortStatus mPortStatus[2];
+    bool mSignalledEOS;
+    bool mNoMoreOutputData;
+    int64_t mSeekTimeUs;
+
+    Mutex mLock;
+    Condition mAsyncCompletion;
+
+    // A list of indices into mPortStatus[kPortIndexOutput] filled with data.
+    List<size_t> mFilledBuffers;
+    Condition mBufferFilled;
+
+    OMXCodec(const sp<IOMX> &omx, IOMX::node_id node, uint32_t quirks,
+             bool isEncoder, const char *mime, const char *componentName,
+             const sp<MediaSource> &source);
+
+    void addCodecSpecificData(const void *data, size_t size);
+    void clearCodecSpecificData();
+
+    void setAMRFormat();
+    void setAACFormat();
+
+    status_t setVideoPortFormatType(
+            OMX_U32 portIndex,
+            OMX_VIDEO_CODINGTYPE compressionFormat,
+            OMX_COLOR_FORMATTYPE colorFormat);
+
+    void setVideoInputFormat(
+            const char *mime, OMX_U32 width, OMX_U32 height);
+
+    void setVideoOutputFormat(
+            const char *mime, OMX_U32 width, OMX_U32 height);
+
+    void setImageOutputFormat(
+            OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height);
+
+    status_t allocateBuffers();
+    status_t allocateBuffersOnPort(OMX_U32 portIndex);
+
+    status_t freeBuffersOnPort(
+            OMX_U32 portIndex, bool onlyThoseWeOwn = false);
+
+    void drainInputBuffer(IOMX::buffer_id buffer);
+    void fillOutputBuffer(IOMX::buffer_id buffer);
+    void drainInputBuffer(BufferInfo *info);
+    void fillOutputBuffer(BufferInfo *info);
+
+    void drainInputBuffers();
+    void fillOutputBuffers();
+
+    void flushPortAsync(OMX_U32 portIndex);
+    void disablePortAsync(OMX_U32 portIndex);
+    void enablePortAsync(OMX_U32 portIndex);
+
+    static size_t countBuffersWeOwn(const Vector<BufferInfo> &buffers);
+    static bool isIntermediateState(State state);
+
+    void onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
+    void onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data);
+    void onStateChange(OMX_STATETYPE newState);
+    void onPortSettingsChanged(OMX_U32 portIndex);
+
+    void setState(State newState);
+
+    status_t init();
+    void initOutputFormat(const sp<MetaData> &inputFormat);
+
+    void dumpPortStatus(OMX_U32 portIndex);
+
+    OMXCodec(const OMXCodec &);
+    OMXCodec &operator=(const OMXCodec &);
+};
+
+}  // namespace android
+
+#endif  // OMX_CODEC_H_
diff --git a/include/media/stagefright/OMXDecoder.h b/include/media/stagefright/OMXDecoder.h
index c6b7cb3..0abc5a6 100644
--- a/include/media/stagefright/OMXDecoder.h
+++ b/include/media/stagefright/OMXDecoder.h
@@ -36,14 +36,10 @@
                    public OMXObserver,
                    public MediaBufferObserver {
 public:
-    static OMXDecoder *Create(
+    static sp<OMXDecoder> Create(
             OMXClient *client, const sp<MetaData> &data,
-            bool createEncoder = false);
-
-    virtual ~OMXDecoder();
-
-    // Caller retains ownership of "source".
-    void setSource(MediaSource *source);
+            bool createEncoder,
+            const sp<MediaSource> &source);
 
     virtual status_t start(MetaData *params = NULL);
     virtual status_t stop();
@@ -61,6 +57,9 @@
     // from MediaBufferObserver
     virtual void signalBufferReturned(MediaBuffer *buffer);
 
+protected:
+    virtual ~OMXDecoder();
+
 private:
     enum {
         kPortIndexInput  = 0,
@@ -97,7 +96,7 @@
     bool mIsEncoder;
     uint32_t mQuirks;
 
-    MediaSource *mSource;
+    sp<MediaSource> mSource;
     sp<MetaData> mOutputFormat;
 
     Mutex mLock;
@@ -135,7 +134,8 @@
     OMXDecoder(OMXClient *client, IOMX::node_id node,
                const char *mime, const char *codec,
                bool is_encoder,
-               uint32_t quirks);
+               uint32_t quirks,
+               const sp<MediaSource> &source);
 
     void setPortStatus(OMX_U32 port_index, PortStatus status);
     PortStatus getPortStatus(OMX_U32 port_index) const;
diff --git a/include/media/stagefright/SampleTable.h b/include/media/stagefright/SampleTable.h
index 712da10..808d142 100644
--- a/include/media/stagefright/SampleTable.h
+++ b/include/media/stagefright/SampleTable.h
@@ -22,17 +22,16 @@
 #include <stdint.h>
 
 #include <media/stagefright/MediaErrors.h>
+#include <utils/RefBase.h>
 #include <utils/threads.h>
 
 namespace android {
 
 class DataSource;
 
-class SampleTable {
+class SampleTable : public RefBase {
 public:
-    // Caller retains ownership of "source".
-    SampleTable(DataSource *source);
-    ~SampleTable();
+    SampleTable(const sp<DataSource> &source);
 
     // type can be 'stco' or 'co64'.
     status_t setChunkOffsetParams(
@@ -76,8 +75,11 @@
     status_t findClosestSyncSample(
             uint32_t start_sample_index, uint32_t *sample_index);
 
+protected:
+    ~SampleTable();
+
 private:
-    DataSource *mDataSource;
+    sp<DataSource> mDataSource;
     Mutex mLock;
 
     off_t mChunkOffsetOffset;