diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h
index 76c45a0..dbcdf92 100644
--- a/include/media/IMediaPlayerService.h
+++ b/include/media/IMediaPlayerService.h
@@ -50,6 +50,8 @@
     virtual sp<IOMX>            getOMX() = 0;
     virtual sp<ICrypto>         makeCrypto() = 0;
 
+    virtual status_t enableRemoteDisplay(bool enable) = 0;
+
     // codecs and audio devices usage tracking for the battery app
     enum BatteryDataBits {
         // tracking audio codec
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 2371619..500dde6 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -25,6 +25,8 @@
 #include <media/stagefright/SkipCutBuffer.h>
 #include <OMX_Audio.h>
 
+#define TRACK_BUFFER_TIMING     0
+
 namespace android {
 
 struct ABuffer;
@@ -127,6 +129,15 @@
         sp<GraphicBuffer> mGraphicBuffer;
     };
 
+#if TRACK_BUFFER_TIMING
+    struct BufferStats {
+        int64_t mEmptyBufferTimeUs;
+        int64_t mFillBufferDoneTimeUs;
+    };
+
+    KeyedVector<int64_t, BufferStats> mBufferStats;
+#endif
+
     sp<AMessage> mNotify;
 
     sp<UninitializedState> mUninitializedState;
diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp
index 9120617..41969b1 100644
--- a/media/libmedia/IMediaPlayerService.cpp
+++ b/media/libmedia/IMediaPlayerService.cpp
@@ -38,6 +38,7 @@
     CREATE_METADATA_RETRIEVER,
     GET_OMX,
     MAKE_CRYPTO,
+    ENABLE_REMOTE_DISPLAY,
     ADD_BATTERY_DATA,
     PULL_BATTERY_DATA
 };
@@ -120,6 +121,14 @@
         return interface_cast<ICrypto>(reply.readStrongBinder());
     }
 
+    virtual status_t enableRemoteDisplay(bool enable) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
+        data.writeInt32(enable);
+        remote()->transact(ENABLE_REMOTE_DISPLAY, data, &reply);
+        return reply.readInt32();
+    }
+
     virtual void addBatteryData(uint32_t params) {
         Parcel data, reply;
         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
@@ -206,6 +215,12 @@
             reply->writeStrongBinder(crypto->asBinder());
             return NO_ERROR;
         } break;
+        case ENABLE_REMOTE_DISPLAY: {
+            CHECK_INTERFACE(IMediaPlayerService, data, reply);
+            bool enable = data.readInt32();
+            reply->writeInt32(enableRemoteDisplay(enable));
+            return NO_ERROR;
+        } break;
         case ADD_BATTERY_DATA: {
             CHECK_INTERFACE(IMediaPlayerService, data, reply);
             uint32_t params = data.readInt32();
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index 1373d3c..c7227b0 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -9,45 +9,47 @@
 LOCAL_SRC_FILES:=               \
     ActivityManager.cpp         \
     Crypto.cpp                  \
-    MediaRecorderClient.cpp     \
     MediaPlayerFactory.cpp      \
     MediaPlayerService.cpp      \
+    MediaRecorderClient.cpp     \
     MetadataRetrieverClient.cpp \
-    TestPlayerStub.cpp          \
-    MidiMetadataRetriever.cpp   \
     MidiFile.cpp                \
+    MidiMetadataRetriever.cpp   \
+    RemoteDisplay.cpp           \
     StagefrightPlayer.cpp       \
-    StagefrightRecorder.cpp
+    StagefrightRecorder.cpp     \
+    TestPlayerStub.cpp          \
 
-LOCAL_SHARED_LIBRARIES :=     		\
-	libcutils             			\
-	libutils              			\
-	libbinder             			\
-	libvorbisidec         			\
-	libsonivox            			\
-	libmedia              			\
-	libmedia_native       			\
-	libcamera_client      			\
-	libstagefright        			\
-	libstagefright_omx    			\
-	libstagefright_foundation       \
-	libgui                          \
-	libdl
+LOCAL_SHARED_LIBRARIES :=       \
+    libbinder                   \
+    libcamera_client            \
+    libcutils                   \
+    libdl                       \
+    libgui                      \
+    libmedia                    \
+    libmedia_native             \
+    libsonivox                  \
+    libstagefright              \
+    libstagefright_foundation   \
+    libstagefright_omx          \
+    libstagefright_wfd          \
+    libutils                    \
+    libvorbisidec               \
 
-LOCAL_STATIC_LIBRARIES := \
-        libstagefright_nuplayer                 \
-        libstagefright_rtsp                     \
+LOCAL_STATIC_LIBRARIES :=       \
+    libstagefright_nuplayer     \
+    libstagefright_rtsp         \
 
-LOCAL_C_INCLUDES :=                                               \
-	$(call include-path-for, graphics corecg)                       \
-	$(TOP)/frameworks/av/media/libstagefright/include               \
-	$(TOP)/frameworks/av/media/libstagefright/rtsp                  \
-	$(TOP)/frameworks/native/include/media/openmax                  \
-	$(TOP)/external/tremolo/Tremolo                                 \
+LOCAL_C_INCLUDES :=                                                 \
+    $(call include-path-for, graphics corecg)                       \
+    $(TOP)/frameworks/av/media/libstagefright/include               \
+    $(TOP)/frameworks/av/media/libstagefright/rtsp                  \
+    $(TOP)/frameworks/av/media/libstagefright/wifi-display          \
+    $(TOP)/frameworks/native/include/media/openmax                  \
+    $(TOP)/external/tremolo/Tremolo                                 \
 
 LOCAL_MODULE:= libmediaplayerservice
 
 include $(BUILD_SHARED_LIBRARY)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
-
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 6346363..5fe446f 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -70,6 +70,7 @@
 #include <OMX.h>
 
 #include "Crypto.h"
+#include "RemoteDisplay.h"
 
 namespace {
 using android::media::Metadata;
@@ -278,6 +279,28 @@
     return new Crypto;
 }
 
+status_t MediaPlayerService::enableRemoteDisplay(bool enable) {
+    Mutex::Autolock autoLock(mLock);
+
+    if (enable && mRemoteDisplay == NULL) {
+        mRemoteDisplay = new RemoteDisplay;
+
+        status_t err = mRemoteDisplay->start();
+
+        if (err != OK) {
+            mRemoteDisplay.clear();
+            return err;
+        }
+
+        return OK;
+    } else if (!enable && mRemoteDisplay != NULL) {
+        mRemoteDisplay->stop();
+        mRemoteDisplay.clear();
+    }
+
+    return OK;
+}
+
 status_t MediaPlayerService::AudioCache::dump(int fd, const Vector<String16>& args) const
 {
     const size_t SIZE = 256;
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 6ede9a4..8fbc5d5 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -42,6 +42,7 @@
 class IMediaMetadataRetriever;
 class IOMX;
 class MediaRecorderClient;
+struct RemoteDisplay;
 
 #define CALLBACK_ANTAGONIZER 0
 #if CALLBACK_ANTAGONIZER
@@ -247,6 +248,7 @@
     virtual sp<IMemory>         decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat);
     virtual sp<IOMX>            getOMX();
     virtual sp<ICrypto>         makeCrypto();
+    virtual status_t            enableRemoteDisplay(bool enable);
 
     virtual status_t            dump(int fd, const Vector<String16>& args);
 
@@ -423,6 +425,7 @@
                 int32_t                     mNextConnId;
                 sp<IOMX>                    mOMX;
                 sp<ICrypto>                 mCrypto;
+                sp<RemoteDisplay>           mRemoteDisplay;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/media/libmediaplayerservice/RemoteDisplay.cpp b/media/libmediaplayerservice/RemoteDisplay.cpp
new file mode 100644
index 0000000..855824a
--- /dev/null
+++ b/media/libmediaplayerservice/RemoteDisplay.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "RemoteDisplay.h"
+
+#include "ANetworkSession.h"
+#include "source/WifiDisplaySource.h"
+
+namespace android {
+
+RemoteDisplay::RemoteDisplay()
+    : mInitCheck(NO_INIT),
+      mLooper(new ALooper),
+      mNetSession(new ANetworkSession),
+      mSource(new WifiDisplaySource(mNetSession)) {
+    mLooper->registerHandler(mSource);
+}
+
+RemoteDisplay::~RemoteDisplay() {
+}
+
+status_t RemoteDisplay::start() {
+    mNetSession->start();
+    mLooper->start();
+
+    // XXX replace with 8554 for bcom dongle (it doesn't respect the
+    // default port or the one advertised in the wfd IE).
+    mSource->start(WifiDisplaySource::kWifiDisplayDefaultPort);
+
+    return OK;
+}
+
+status_t RemoteDisplay::stop() {
+    mSource->stop();
+
+    mLooper->stop();
+    mNetSession->stop();
+
+    return OK;
+}
+
+}  // namespace android
+
diff --git a/media/libmediaplayerservice/RemoteDisplay.h b/media/libmediaplayerservice/RemoteDisplay.h
new file mode 100644
index 0000000..6b37afb
--- /dev/null
+++ b/media/libmediaplayerservice/RemoteDisplay.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef REMOTE_DISPLAY_H_
+
+#define REMOTE_DISPLAY_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+struct ALooper;
+struct ANetworkSession;
+struct WifiDisplaySource;
+
+struct RemoteDisplay : public RefBase {
+    RemoteDisplay();
+
+    status_t start();
+    status_t stop();
+
+protected:
+    virtual ~RemoteDisplay();
+
+private:
+    status_t mInitCheck;
+
+    sp<ALooper> mNetLooper;
+    sp<ALooper> mLooper;
+    sp<ANetworkSession> mNetSession;
+    sp<WifiDisplaySource> mSource;
+
+    DISALLOW_EVIL_CONSTRUCTORS(RemoteDisplay);
+};
+
+}  // namespace android
+
+#endif  // REMOTE_DISPLAY_H_
+
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index c37d2ca..3dd5d60 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -861,6 +861,20 @@
         return INVALID_OPERATION;
     }
 
+    int32_t storeMeta;
+    if (encoder
+            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
+            && storeMeta != 0) {
+        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
+
+        if (err != OK) {
+            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
+                  mComponentName.c_str(), err);
+
+            return err;
+        }
+    }
+
     if (!strncasecmp(mime, "video/", 6)) {
         if (encoder) {
             err = setupVideoEncoder(mime, msg);
@@ -2424,6 +2438,21 @@
     CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
     info->mStatus = BufferInfo::OWNED_BY_US;
 
+    const sp<AMessage> &bufferMeta = info->mData->meta();
+    void *mediaBuffer;
+    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
+            && mediaBuffer != NULL) {
+        // We're in "store-metadata-in-buffers" mode, the underlying
+        // OMX component had access to data that's implicitly refcounted
+        // by this "mediaBuffer" object. Now that the OMX component has
+        // told us that it's done with the input buffer, we can decrement
+        // the mediaBuffer's reference count.
+        ((MediaBuffer *)mediaBuffer)->release();
+        mediaBuffer = NULL;
+
+        bufferMeta->setPointer("mediaBuffer", NULL);
+    }
+
     PortMode mode = getPortMode(kPortIndexInput);
 
     switch (mode) {
@@ -2531,10 +2560,10 @@
                 }
 
                 if (buffer != info->mData) {
-                    if (0 && !(flags & OMX_BUFFERFLAG_CODECCONFIG)) {
-                        ALOGV("[%s] Needs to copy input data.",
-                             mCodec->mComponentName.c_str());
-                    }
+                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
+                         mCodec->mComponentName.c_str(),
+                         bufferID,
+                         buffer.get(), info->mData.get());
 
                     CHECK_LE(buffer->size(), info->mData->capacity());
                     memcpy(info->mData->data(), buffer->data(), buffer->size());
@@ -2547,10 +2576,22 @@
                     ALOGV("[%s] calling emptyBuffer %p w/ EOS",
                          mCodec->mComponentName.c_str(), bufferID);
                 } else {
+#if TRACK_BUFFER_TIMING
+                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
+                         mCodec->mComponentName.c_str(), bufferID, timeUs);
+#else
                     ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
                          mCodec->mComponentName.c_str(), bufferID, timeUs);
+#endif
                 }
 
+#if TRACK_BUFFER_TIMING
+                ACodec::BufferStats stats;
+                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
+                stats.mFillBufferDoneTimeUs = -1ll;
+                mCodec->mBufferStats.add(timeUs, stats);
+#endif
+
                 CHECK_EQ(mCodec->mOMX->emptyBuffer(
                             mCodec->mNode,
                             bufferID,
@@ -2647,6 +2688,22 @@
          mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
 
     ssize_t index;
+
+#if TRACK_BUFFER_TIMING
+    index = mCodec->mBufferStats.indexOfKey(timeUs);
+    if (index >= 0) {
+        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
+        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
+
+        ALOGI("frame PTS %lld: %lld",
+                timeUs,
+                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
+
+        mCodec->mBufferStats.removeItemsAt(index);
+        stats = NULL;
+    }
+#endif
+
     BufferInfo *info =
         mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
 
@@ -2891,7 +2948,7 @@
     AString mime;
 
     AString componentName;
-    uint32_t quirks;
+    uint32_t quirks = 0;
     if (msg->findString("componentName", &componentName)) {
         ssize_t index = matchingCodecs.add();
         OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
diff --git a/media/libstagefright/wifi-display/ANetworkSession.h b/media/libstagefright/wifi-display/ANetworkSession.h
index 0402317..d4cd14f 100644
--- a/media/libstagefright/wifi-display/ANetworkSession.h
+++ b/media/libstagefright/wifi-display/ANetworkSession.h
@@ -27,6 +27,8 @@
 
 struct AMessage;
 
+// Helper class to manage a number of live sockets (datagram and stream-based)
+// on a single thread. Clients are notified about activity through AMessages.
 struct ANetworkSession : public RefBase {
     ANetworkSession();
 
diff --git a/media/libstagefright/wifi-display/Android.mk b/media/libstagefright/wifi-display/Android.mk
index 114ff62..b035a51 100644
--- a/media/libstagefright/wifi-display/Android.mk
+++ b/media/libstagefright/wifi-display/Android.mk
@@ -3,9 +3,42 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-        udptest.cpp                 \
-        ANetworkSession.cpp         \
-        ParsedMessage.cpp           \
+        ANetworkSession.cpp             \
+        ParsedMessage.cpp               \
+        source/Converter.cpp            \
+        source/PlaybackSession.cpp      \
+        source/RepeaterSource.cpp       \
+        source/Serializer.cpp           \
+        source/TSPacketizer.cpp         \
+        source/WifiDisplaySource.cpp    \
+
+LOCAL_C_INCLUDES:= \
+        $(TOP)/frameworks/av/media/libstagefright \
+        $(TOP)/frameworks/native/include/media/openmax \
+        $(TOP)/frameworks/av/media/libstagefright/mpeg2ts \
+
+LOCAL_SHARED_LIBRARIES:= \
+        libbinder                       \
+        libcutils                       \
+        libgui                          \
+        libmedia                        \
+        libstagefright                  \
+        libstagefright_foundation       \
+        libui                           \
+        libutils                        \
+
+LOCAL_MODULE:= libstagefright_wfd
+
+LOCAL_MODULE_TAGS:= optional
+
+include $(BUILD_SHARED_LIBRARY)
+
+################################################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+        wfd.cpp                 \
 
 LOCAL_SHARED_LIBRARIES:= \
         libbinder                       \
@@ -13,6 +46,29 @@
         libmedia                        \
         libstagefright                  \
         libstagefright_foundation       \
+        libstagefright_wfd              \
+        libutils                        \
+
+LOCAL_MODULE:= wfd
+
+LOCAL_MODULE_TAGS := debug
+
+include $(BUILD_EXECUTABLE)
+
+################################################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+        udptest.cpp                 \
+
+LOCAL_SHARED_LIBRARIES:= \
+        libbinder                       \
+        libgui                          \
+        libmedia                        \
+        libstagefright                  \
+        libstagefright_foundation       \
+        libstagefright_wfd              \
         libutils                        \
 
 LOCAL_MODULE:= udptest
diff --git a/media/libstagefright/wifi-display/ParsedMessage.h b/media/libstagefright/wifi-display/ParsedMessage.h
index 00f578f..e9a1859 100644
--- a/media/libstagefright/wifi-display/ParsedMessage.h
+++ b/media/libstagefright/wifi-display/ParsedMessage.h
@@ -21,6 +21,8 @@
 
 namespace android {
 
+// Encapsulates an "HTTP/RTSP style" response, i.e. a status line,
+// key/value pairs making up the headers and an optional body/content.
 struct ParsedMessage : public RefBase {
     static sp<ParsedMessage> Parse(
             const char *data, size_t size, bool noMoreData, size_t *length);
diff --git a/media/libstagefright/wifi-display/source/Converter.cpp b/media/libstagefright/wifi-display/source/Converter.cpp
new file mode 100644
index 0000000..655fbae
--- /dev/null
+++ b/media/libstagefright/wifi-display/source/Converter.cpp
@@ -0,0 +1,281 @@
+/*
+ * Copyright 2012, 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 "Converter"
+#include <utils/Log.h>
+
+#include "Converter.h"
+
+#include <gui/SurfaceTextureClient.h>
+#include <media/ICrypto.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/MediaCodec.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
+
+namespace android {
+
+Converter::Converter(
+        const sp<AMessage> &notify,
+        const sp<ALooper> &codecLooper,
+        const sp<AMessage> &format)
+    : mInitCheck(NO_INIT),
+      mNotify(notify),
+      mCodecLooper(codecLooper),
+      mInputFormat(format),
+      mDoMoreWorkPending(false) {
+    mInitCheck = initEncoder();
+}
+
+Converter::~Converter() {
+    if (mEncoder != NULL) {
+        mEncoder->release();
+        mEncoder.clear();
+    }
+}
+
+status_t Converter::initCheck() const {
+    return mInitCheck;
+}
+
+sp<AMessage> Converter::getOutputFormat() const {
+    return mOutputFormat;
+}
+
+status_t Converter::initEncoder() {
+    AString inputMIME;
+    CHECK(mInputFormat->findString("mime", &inputMIME));
+
+    AString outputMIME;
+    bool isAudio = false;
+    if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_AUDIO_RAW)) {
+        outputMIME = MEDIA_MIMETYPE_AUDIO_AAC;
+        isAudio = true;
+    } else if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_VIDEO_RAW)) {
+        outputMIME = MEDIA_MIMETYPE_VIDEO_AVC;
+    } else {
+        TRESPASS();
+    }
+
+    mEncoder = MediaCodec::CreateByType(
+            mCodecLooper, outputMIME.c_str(), true /* encoder */);
+
+    if (mEncoder == NULL) {
+        return ERROR_UNSUPPORTED;
+    }
+
+    mOutputFormat = mInputFormat->dup();
+    mOutputFormat->setString("mime", outputMIME.c_str());
+
+    if (isAudio) {
+        mOutputFormat->setInt32("bitrate", 64000);      // 64 kBit/sec
+    } else {
+        mOutputFormat->setInt32("bitrate", 3000000);    // 3Mbit/sec
+        mOutputFormat->setInt32("frame-rate", 30);
+        mOutputFormat->setInt32("i-frame-interval", 3);  // Iframes every 3 secs
+    }
+
+    ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str());
+
+    status_t err = mEncoder->configure(
+            mOutputFormat,
+            NULL /* nativeWindow */,
+            NULL /* crypto */,
+            MediaCodec::CONFIGURE_FLAG_ENCODE);
+
+    if (err != OK) {
+        return err;
+    }
+
+    err = mEncoder->start();
+
+    if (err != OK) {
+        return err;
+    }
+
+    err = mEncoder->getInputBuffers(&mEncoderInputBuffers);
+
+    if (err != OK) {
+        return err;
+    }
+
+    return mEncoder->getOutputBuffers(&mEncoderOutputBuffers);
+}
+
+void Converter::feedAccessUnit(const sp<ABuffer> &accessUnit) {
+    sp<AMessage> msg = new AMessage(kWhatFeedAccessUnit, id());
+    msg->setBuffer("accessUnit", accessUnit);
+    msg->post();
+}
+
+void Converter::signalEOS() {
+    (new AMessage(kWhatInputEOS, id()))->post();
+}
+
+void Converter::notifyError(status_t err) {
+    sp<AMessage> notify = mNotify->dup();
+    notify->setInt32("what", kWhatError);
+    notify->setInt32("err", err);
+    notify->post();
+}
+
+void Converter::onMessageReceived(const sp<AMessage> &msg) {
+    switch (msg->what()) {
+        case kWhatFeedAccessUnit:
+        {
+            sp<ABuffer> accessUnit;
+            CHECK(msg->findBuffer("accessUnit", &accessUnit));
+
+            mInputBufferQueue.push_back(accessUnit);
+
+            feedEncoderInputBuffers();
+
+            scheduleDoMoreWork();
+            break;
+        }
+
+        case kWhatInputEOS:
+        {
+            mInputBufferQueue.push_back(NULL);
+
+            feedEncoderInputBuffers();
+
+            scheduleDoMoreWork();
+            break;
+        }
+
+        case kWhatDoMoreWork:
+        {
+            mDoMoreWorkPending = false;
+            status_t err = doMoreWork();
+
+            if (err != OK) {
+                notifyError(err);
+            } else {
+                scheduleDoMoreWork();
+            }
+            break;
+        }
+
+        default:
+            TRESPASS();
+    }
+}
+
+void Converter::scheduleDoMoreWork() {
+    if (mDoMoreWorkPending) {
+        return;
+    }
+
+    mDoMoreWorkPending = true;
+    (new AMessage(kWhatDoMoreWork, id()))->post(1000ll);
+}
+
+status_t Converter::feedEncoderInputBuffers() {
+    while (!mInputBufferQueue.empty()
+            && !mAvailEncoderInputIndices.empty()) {
+        sp<ABuffer> buffer = *mInputBufferQueue.begin();
+        mInputBufferQueue.erase(mInputBufferQueue.begin());
+
+        size_t bufferIndex = *mAvailEncoderInputIndices.begin();
+        mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin());
+
+        int64_t timeUs = 0ll;
+        uint32_t flags = 0;
+
+        if (buffer != NULL) {
+            CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
+
+            memcpy(mEncoderInputBuffers.itemAt(bufferIndex)->data(),
+                   buffer->data(),
+                   buffer->size());
+
+            void *mediaBuffer;
+            if (buffer->meta()->findPointer("mediaBuffer", &mediaBuffer)
+                    && mediaBuffer != NULL) {
+                mEncoderInputBuffers.itemAt(bufferIndex)->meta()
+                    ->setPointer("mediaBuffer", mediaBuffer);
+
+                buffer->meta()->setPointer("mediaBuffer", NULL);
+            }
+        } else {
+            flags = MediaCodec::BUFFER_FLAG_EOS;
+        }
+
+        status_t err = mEncoder->queueInputBuffer(
+                bufferIndex, 0, (buffer == NULL) ? 0 : buffer->size(),
+                timeUs, flags);
+
+        if (err != OK) {
+            return err;
+        }
+    }
+
+    return OK;
+}
+
+status_t Converter::doMoreWork() {
+    size_t bufferIndex;
+    status_t err = mEncoder->dequeueInputBuffer(&bufferIndex);
+
+    if (err == OK) {
+        mAvailEncoderInputIndices.push_back(bufferIndex);
+        feedEncoderInputBuffers();
+    }
+
+    size_t offset;
+    size_t size;
+    int64_t timeUs;
+    uint32_t flags;
+    err = mEncoder->dequeueOutputBuffer(
+            &bufferIndex, &offset, &size, &timeUs, &flags);
+
+    if (err == OK) {
+        if (flags & MediaCodec::BUFFER_FLAG_EOS) {
+            sp<AMessage> notify = mNotify->dup();
+            notify->setInt32("what", kWhatEOS);
+            notify->post();
+        } else {
+            sp<ABuffer> buffer = new ABuffer(size);
+            buffer->meta()->setInt64("timeUs", timeUs);
+
+            memcpy(buffer->data(),
+                   mEncoderOutputBuffers.itemAt(bufferIndex)->base() + offset,
+                   size);
+
+            if (flags & MediaCodec::BUFFER_FLAG_CODECCONFIG) {
+                mOutputFormat->setBuffer("csd-0", buffer);
+            } else {
+                sp<AMessage> notify = mNotify->dup();
+                notify->setInt32("what", kWhatAccessUnit);
+                notify->setBuffer("accessUnit", buffer);
+                notify->post();
+            }
+        }
+
+        err = mEncoder->releaseOutputBuffer(bufferIndex);
+    } else if (err == -EAGAIN) {
+        err = OK;
+    }
+
+    return err;
+}
+
+}  // namespace android
+
diff --git a/media/libstagefright/wifi-display/source/Converter.h b/media/libstagefright/wifi-display/source/Converter.h
new file mode 100644
index 0000000..6700a32
--- /dev/null
+++ b/media/libstagefright/wifi-display/source/Converter.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2012, 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 CONVERTER_H_
+
+#define CONVERTER_H_
+
+#include <media/stagefright/foundation/AHandler.h>
+
+namespace android {
+
+struct ABuffer;
+struct MediaCodec;
+
+// Utility class that receives media access units and converts them into
+// media access unit of a different format.
+// Right now this'll convert raw video into H.264 and raw audio into AAC.
+struct Converter : public AHandler {
+    Converter(
+            const sp<AMessage> &notify,
+            const sp<ALooper> &codecLooper,
+            const sp<AMessage> &format);
+
+    status_t initCheck() const;
+
+    sp<AMessage> getOutputFormat() const;
+
+    void feedAccessUnit(const sp<ABuffer> &accessUnit);
+    void signalEOS();
+
+    enum {
+        kWhatAccessUnit,
+        kWhatEOS,
+        kWhatError,
+    };
+
+protected:
+    virtual ~Converter();
+    virtual void onMessageReceived(const sp<AMessage> &msg);
+
+private:
+    enum {
+        kWhatFeedAccessUnit,
+        kWhatInputEOS,
+        kWhatDoMoreWork
+    };
+
+    status_t mInitCheck;
+    sp<AMessage> mNotify;
+    sp<ALooper> mCodecLooper;
+    sp<AMessage> mInputFormat;
+    sp<AMessage> mOutputFormat;
+
+    sp<MediaCodec> mEncoder;
+
+    Vector<sp<ABuffer> > mEncoderInputBuffers;
+    Vector<sp<ABuffer> > mEncoderOutputBuffers;
+
+    List<size_t> mAvailEncoderInputIndices;
+
+    List<sp<ABuffer> > mInputBufferQueue;
+
+    bool mDoMoreWorkPending;
+
+    status_t initEncoder();
+
+    status_t feedEncoderInputBuffers();
+
+    void scheduleDoMoreWork();
+    status_t doMoreWork();
+
+    void notifyError(status_t err);
+
+    DISALLOW_EVIL_CONSTRUCTORS(Converter);
+};
+
+}  // namespace android
+
+#endif  // CONVERTER_H_
+
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
new file mode 100644
index 0000000..5095c15
--- /dev/null
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
@@ -0,0 +1,952 @@
+/*
+ * Copyright 2012, 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 "PlaybackSession"
+#include <utils/Log.h>
+
+#include "PlaybackSession.h"
+
+#include "Converter.h"
+#include "RepeaterSource.h"
+#include "Serializer.h"
+#include "TSPacketizer.h"
+
+#include <binder/IServiceManager.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/SurfaceComposerClient.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/hexdump.h>
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaExtractor.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/MPEG2TSWriter.h>
+#include <media/stagefright/SurfaceMediaSource.h>
+#include <media/stagefright/Utils.h>
+#include <ui/DisplayInfo.h>
+
+#include <OMX_IVCommon.h>
+
+#define FAKE_VIDEO      0
+
+namespace android {
+
+static size_t kMaxRTPPacketSize = 1500;
+static size_t kMaxNumTSPacketsPerRTPPacket = (kMaxRTPPacketSize - 12) / 188;
+
+struct WifiDisplaySource::PlaybackSession::Track : public RefBase {
+    Track(const sp<Converter> &converter);
+    Track(const sp<AMessage> &format);
+
+    sp<AMessage> getFormat();
+
+    const sp<Converter> &converter() const;
+    ssize_t packetizerTrackIndex() const;
+
+    void setPacketizerTrackIndex(size_t index);
+
+protected:
+    virtual ~Track();
+
+private:
+    sp<Converter> mConverter;
+    sp<AMessage> mFormat;
+    ssize_t mPacketizerTrackIndex;
+
+    DISALLOW_EVIL_CONSTRUCTORS(Track);
+};
+
+WifiDisplaySource::PlaybackSession::Track::Track(const sp<Converter> &converter)
+    : mConverter(converter),
+      mPacketizerTrackIndex(-1) {
+}
+
+WifiDisplaySource::PlaybackSession::Track::Track(const sp<AMessage> &format)
+    : mFormat(format),
+      mPacketizerTrackIndex(-1) {
+}
+
+WifiDisplaySource::PlaybackSession::Track::~Track() {
+}
+
+sp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() {
+    if (mFormat != NULL) {
+        return mFormat;
+    }
+
+    return mConverter->getOutputFormat();
+}
+
+const sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() const {
+    return mConverter;
+}
+
+ssize_t WifiDisplaySource::PlaybackSession::Track::packetizerTrackIndex() const {
+    return mPacketizerTrackIndex;
+}
+
+void WifiDisplaySource::PlaybackSession::Track::setPacketizerTrackIndex(size_t index) {
+    CHECK_LT(mPacketizerTrackIndex, 0);
+    mPacketizerTrackIndex = index;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+WifiDisplaySource::PlaybackSession::PlaybackSession(
+        const sp<ANetworkSession> &netSession,
+        const sp<AMessage> &notify)
+    : mNetSession(netSession),
+      mNotify(notify),
+      mLastLifesignUs(),
+      mTSQueue(new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188)),
+      mPrevTimeUs(-1ll),
+      mUseInterleavedTCP(false),
+      mRTPChannel(0),
+      mRTCPChannel(0),
+      mRTPPort(0),
+      mRTPSessionID(0),
+      mRTCPSessionID(0),
+      mRTPSeqNo(0),
+      mLastNTPTime(0),
+      mLastRTPTime(0),
+      mNumRTPSent(0),
+      mNumRTPOctetsSent(0),
+      mNumSRsSent(0),
+      mSendSRPending(false),
+      mFirstPacketTimeUs(-1ll),
+      mHistoryLength(0) {
+    mTSQueue->setRange(0, 12);
+}
+
+status_t WifiDisplaySource::PlaybackSession::init(
+        const char *clientIP, int32_t clientRtp, int32_t clientRtcp,
+        bool useInterleavedTCP) {
+    status_t err = setupPacketizer();
+
+    if (err != OK) {
+        return err;
+    }
+
+    if (useInterleavedTCP) {
+        mUseInterleavedTCP = true;
+        mRTPChannel = clientRtp;
+        mRTCPChannel = clientRtcp;
+        mRTPPort = 0;
+        mRTPSessionID = 0;
+        mRTCPSessionID = 0;
+
+        updateLiveness();
+        return OK;
+    }
+
+    mUseInterleavedTCP = false;
+    mRTPChannel = 0;
+    mRTCPChannel = 0;
+
+    int serverRtp;
+
+    sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id());
+    sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id());
+    for (serverRtp = 15550;; serverRtp += 2) {
+        int32_t rtpSession;
+        err = mNetSession->createUDPSession(
+                    serverRtp, clientIP, clientRtp,
+                    rtpNotify, &rtpSession);
+
+        if (err != OK) {
+            ALOGI("failed to create RTP socket on port %d", serverRtp);
+            continue;
+        }
+
+        if (clientRtcp < 0) {
+            // No RTCP.
+
+            mRTPPort = serverRtp;
+            mRTPSessionID = rtpSession;
+            mRTCPSessionID = 0;
+
+            ALOGI("rtpSessionId = %d", rtpSession);
+            break;
+        }
+
+        int32_t rtcpSession;
+        err = mNetSession->createUDPSession(
+                serverRtp + 1, clientIP, clientRtcp,
+                rtcpNotify, &rtcpSession);
+
+        if (err == OK) {
+            mRTPPort = serverRtp;
+            mRTPSessionID = rtpSession;
+            mRTCPSessionID = rtcpSession;
+
+            ALOGI("rtpSessionID = %d, rtcpSessionID = %d", rtpSession, rtcpSession);
+            break;
+        }
+
+        ALOGI("failed to create RTCP socket on port %d", serverRtp + 1);
+        mNetSession->destroySession(rtpSession);
+    }
+
+    if (mRTPPort == 0) {
+        return UNKNOWN_ERROR;
+    }
+
+    updateLiveness();
+
+    return OK;
+}
+
+WifiDisplaySource::PlaybackSession::~PlaybackSession() {
+    mTracks.clear();
+
+    if (mCodecLooper != NULL) {
+        mCodecLooper->stop();
+        mCodecLooper.clear();
+    }
+
+    mPacketizer.clear();
+
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> binder = sm->getService(String16("SurfaceFlinger"));
+    sp<ISurfaceComposer> service = interface_cast<ISurfaceComposer>(binder);
+    CHECK(service != NULL);
+
+    service->connectDisplay(NULL);
+
+    if (mSerializer != NULL) {
+        mSerializer->stop();
+
+        looper()->unregisterHandler(mSerializer->id());
+        mSerializer.clear();
+    }
+
+    if (mSerializerLooper != NULL) {
+        mSerializerLooper->stop();
+        mSerializerLooper.clear();
+    }
+
+    if (mRTCPSessionID != 0) {
+        mNetSession->destroySession(mRTCPSessionID);
+    }
+
+    if (mRTPSessionID != 0) {
+        mNetSession->destroySession(mRTPSessionID);
+    }
+}
+
+int32_t WifiDisplaySource::PlaybackSession::getRTPPort() const {
+    return mRTPPort;
+}
+
+int64_t WifiDisplaySource::PlaybackSession::getLastLifesignUs() const {
+    return mLastLifesignUs;
+}
+
+void WifiDisplaySource::PlaybackSession::updateLiveness() {
+    mLastLifesignUs = ALooper::GetNowUs();
+}
+
+status_t WifiDisplaySource::PlaybackSession::play() {
+    updateLiveness();
+
+    if (mRTCPSessionID != 0) {
+        scheduleSendSR();
+    }
+
+    return mSerializer->start();
+}
+
+status_t WifiDisplaySource::PlaybackSession::pause() {
+    updateLiveness();
+
+    return OK;
+}
+
+void WifiDisplaySource::PlaybackSession::onMessageReceived(
+        const sp<AMessage> &msg) {
+    switch (msg->what()) {
+        case kWhatRTPNotify:
+        case kWhatRTCPNotify:
+        {
+            int32_t reason;
+            CHECK(msg->findInt32("reason", &reason));
+
+            switch (reason) {
+                case ANetworkSession::kWhatError:
+                {
+                    int32_t sessionID;
+                    CHECK(msg->findInt32("sessionID", &sessionID));
+
+                    int32_t err;
+                    CHECK(msg->findInt32("err", &err));
+
+                    int32_t errorOccuredDuringSend;
+                    CHECK(msg->findInt32("send", &errorOccuredDuringSend));
+
+                    AString detail;
+                    CHECK(msg->findString("detail", &detail));
+
+                    if (msg->what() == kWhatRTPNotify
+                            && !errorOccuredDuringSend) {
+                        // This is ok, we don't expect to receive anything on
+                        // the RTP socket.
+                        break;
+                    }
+
+                    ALOGE("An error occurred during %s in session %d "
+                          "(%d, '%s' (%s)).",
+                          errorOccuredDuringSend ? "send" : "receive",
+                          sessionID,
+                          err,
+                          detail.c_str(),
+                          strerror(-err));
+
+                    mNetSession->destroySession(sessionID);
+
+                    if (sessionID == mRTPSessionID) {
+                        mRTPSessionID = 0;
+                    } else if (sessionID == mRTCPSessionID) {
+                        mRTCPSessionID = 0;
+                    }
+
+                    // Inform WifiDisplaySource of our premature death (wish).
+                    sp<AMessage> notify = mNotify->dup();
+                    notify->setInt32("what", kWhatSessionDead);
+                    notify->post();
+                    break;
+                }
+
+                case ANetworkSession::kWhatDatagram:
+                {
+                    int32_t sessionID;
+                    CHECK(msg->findInt32("sessionID", &sessionID));
+
+                    sp<ABuffer> data;
+                    CHECK(msg->findBuffer("data", &data));
+
+                    status_t err;
+                    if (msg->what() == kWhatRTCPNotify) {
+                        err = parseRTCP(data);
+                    }
+                    break;
+                }
+
+                default:
+                    TRESPASS();
+            }
+            break;
+        }
+
+        case kWhatSendSR:
+        {
+            mSendSRPending = false;
+
+            if (mRTCPSessionID == 0) {
+                break;
+            }
+
+            onSendSR();
+
+            scheduleSendSR();
+            break;
+        }
+
+        case kWhatSerializerNotify:
+        {
+            int32_t what;
+            CHECK(msg->findInt32("what", &what));
+
+            if (what == Serializer::kWhatEOS) {
+                ALOGI("input eos");
+
+                for (size_t i = 0; i < mTracks.size(); ++i) {
+#if FAKE_VIDEO
+                    sp<AMessage> msg = new AMessage(kWhatConverterNotify, id());
+                    msg->setInt32("what", Converter::kWhatEOS);
+                    msg->setSize("trackIndex", i);
+                    msg->post();
+#else
+                    mTracks.valueAt(i)->converter()->signalEOS();
+#endif
+                }
+            } else {
+                CHECK_EQ(what, Serializer::kWhatAccessUnit);
+
+                size_t trackIndex;
+                CHECK(msg->findSize("trackIndex", &trackIndex));
+
+                sp<ABuffer> accessUnit;
+                CHECK(msg->findBuffer("accessUnit", &accessUnit));
+
+#if FAKE_VIDEO
+                int64_t timeUs;
+                CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
+
+                void *mbuf;
+                CHECK(accessUnit->meta()->findPointer("mediaBuffer", &mbuf));
+
+                ((MediaBuffer *)mbuf)->release();
+                mbuf = NULL;
+
+                sp<AMessage> msg = new AMessage(kWhatConverterNotify, id());
+                msg->setInt32("what", Converter::kWhatAccessUnit);
+                msg->setSize("trackIndex", trackIndex);
+                msg->setBuffer("accessUnit", accessUnit);
+                msg->post();
+#else
+                mTracks.valueFor(trackIndex)->converter()
+                    ->feedAccessUnit(accessUnit);
+#endif
+            }
+            break;
+        }
+
+        case kWhatConverterNotify:
+        {
+            int32_t what;
+            CHECK(msg->findInt32("what", &what));
+
+            size_t trackIndex;
+            CHECK(msg->findSize("trackIndex", &trackIndex));
+
+            if (what == Converter::kWhatAccessUnit) {
+                const sp<Track> &track = mTracks.valueFor(trackIndex);
+
+                uint32_t flags = 0;
+
+                ssize_t packetizerTrackIndex = track->packetizerTrackIndex();
+                if (packetizerTrackIndex < 0) {
+                    flags = TSPacketizer::EMIT_PAT_AND_PMT;
+
+                    packetizerTrackIndex =
+                        mPacketizer->addTrack(track->getFormat());
+
+                    if (packetizerTrackIndex >= 0) {
+                        track->setPacketizerTrackIndex(packetizerTrackIndex);
+                    }
+                }
+
+                if (packetizerTrackIndex >= 0) {
+                    sp<ABuffer> accessUnit;
+                    CHECK(msg->findBuffer("accessUnit", &accessUnit));
+
+                    int64_t timeUs;
+                    CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
+
+                    if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll >= timeUs) {
+                        flags |= TSPacketizer::EMIT_PCR;
+                        mPrevTimeUs = timeUs;
+                    }
+
+                    sp<ABuffer> packets;
+                    mPacketizer->packetize(
+                            packetizerTrackIndex, accessUnit, &packets, flags);
+
+                    for (size_t offset = 0;
+                            offset < packets->size(); offset += 188) {
+                        bool lastTSPacket = (offset + 188 >= packets->size());
+
+                        appendTSData(
+                                packets->data() + offset,
+                                188,
+                                true /* timeDiscontinuity */,
+                                lastTSPacket /* flush */);
+                    }
+                }
+            } else if (what == Converter::kWhatEOS) {
+                CHECK_EQ(what, Converter::kWhatEOS);
+
+                ALOGI("output EOS on track %d", trackIndex);
+
+                ssize_t index = mTracks.indexOfKey(trackIndex);
+                CHECK_GE(index, 0);
+
+#if !FAKE_VIDEO
+                const sp<Converter> &converter =
+                    mTracks.valueAt(index)->converter();
+                looper()->unregisterHandler(converter->id());
+#endif
+
+                mTracks.removeItemsAt(index);
+
+                if (mTracks.isEmpty()) {
+                    ALOGI("Reached EOS");
+                }
+            } else {
+                CHECK_EQ(what, Converter::kWhatError);
+
+                status_t err;
+                CHECK(msg->findInt32("err", &err));
+
+                ALOGE("converter signaled error %d", err);
+            }
+            break;
+        }
+
+        default:
+            TRESPASS();
+    }
+}
+
+status_t WifiDisplaySource::PlaybackSession::setupPacketizer() {
+    sp<AMessage> msg = new AMessage(kWhatSerializerNotify, id());
+
+    mSerializerLooper = new ALooper;
+    mSerializerLooper->start();
+
+    mSerializer = new Serializer(
+#if FAKE_VIDEO
+            true /* throttled */
+#else
+            false /* throttled */
+#endif
+            , msg);
+    mSerializerLooper->registerHandler(mSerializer);
+
+    mPacketizer = new TSPacketizer;
+
+#if FAKE_VIDEO
+    DataSource::RegisterDefaultSniffers();
+
+    sp<DataSource> dataSource =
+        DataSource::CreateFromURI(
+                "/system/etc/inception_1500.mp4");
+
+    CHECK(dataSource != NULL);
+
+    sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
+    CHECK(extractor != NULL);
+
+    bool haveAudio = false;
+    bool haveVideo = false;
+    for (size_t i = 0; i < extractor->countTracks(); ++i) {
+        sp<MetaData> meta = extractor->getTrackMetaData(i);
+
+        const char *mime;
+        CHECK(meta->findCString(kKeyMIMEType, &mime));
+
+        bool useTrack = false;
+        if (!strncasecmp(mime, "audio/", 6) && !haveAudio) {
+            useTrack = true;
+            haveAudio = true;
+        } else if (!strncasecmp(mime, "video/", 6) && !haveVideo) {
+            useTrack = true;
+            haveVideo = true;
+        }
+
+        if (!useTrack) {
+            continue;
+        }
+
+        sp<MediaSource> source = extractor->getTrack(i);
+
+        ssize_t index = mSerializer->addSource(source);
+        CHECK_GE(index, 0);
+
+        sp<AMessage> format;
+        status_t err = convertMetaDataToMessage(source->getFormat(), &format);
+        CHECK_EQ(err, (status_t)OK);
+
+        mTracks.add(index, new Track(format));
+    }
+    CHECK(haveAudio || haveVideo);
+#else
+    mCodecLooper = new ALooper;
+    mCodecLooper->start();
+
+    DisplayInfo info;
+    SurfaceComposerClient::getDisplayInfo(0, &info);
+
+    // sp<SurfaceMediaSource> source = new SurfaceMediaSource(info.w, info.h);
+    sp<SurfaceMediaSource> source = new SurfaceMediaSource(720, 1280);
+
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> binder = sm->getService(String16("SurfaceFlinger"));
+    sp<ISurfaceComposer> service = interface_cast<ISurfaceComposer>(binder);
+    CHECK(service != NULL);
+
+    service->connectDisplay(source->getBufferQueue());
+
+#if 0
+    {
+        ALOGI("reading buffer");
+
+        CHECK_EQ((status_t)OK, source->start());
+        MediaBuffer *mbuf;
+        CHECK_EQ((status_t)OK, source->read(&mbuf));
+        mbuf->release();
+        mbuf = NULL;
+
+        ALOGI("got buffer");
+    }
+#endif
+
+#if 0
+    ssize_t index = mSerializer->addSource(source);
+#else
+    ssize_t index = mSerializer->addSource(
+            new RepeaterSource(source, 30.0 /* rateHz */));
+#endif
+
+    CHECK_GE(index, 0);
+
+    sp<AMessage> format;
+    status_t err = convertMetaDataToMessage(source->getFormat(), &format);
+    CHECK_EQ(err, (status_t)OK);
+
+    format->setInt32("store-metadata-in-buffers", true);
+
+    format->setInt32(
+            "color-format", OMX_COLOR_FormatAndroidOpaque);
+
+    sp<AMessage> notify = new AMessage(kWhatConverterNotify, id());
+    notify->setSize("trackIndex", index);
+
+    sp<Converter> converter =
+        new Converter(notify, mCodecLooper, format);
+
+    looper()->registerHandler(converter);
+
+    mTracks.add(index, new Track(converter));
+#endif
+
+    return OK;
+}
+
+void WifiDisplaySource::PlaybackSession::scheduleSendSR() {
+    if (mSendSRPending) {
+        return;
+    }
+
+    mSendSRPending = true;
+    (new AMessage(kWhatSendSR, id()))->post(kSendSRIntervalUs);
+}
+
+void WifiDisplaySource::PlaybackSession::addSR(const sp<ABuffer> &buffer) {
+    uint8_t *data = buffer->data() + buffer->size();
+
+    // TODO: Use macros/utility functions to clean up all the bitshifts below.
+
+    data[0] = 0x80 | 0;
+    data[1] = 200;  // SR
+    data[2] = 0;
+    data[3] = 6;
+    data[4] = kSourceID >> 24;
+    data[5] = (kSourceID >> 16) & 0xff;
+    data[6] = (kSourceID >> 8) & 0xff;
+    data[7] = kSourceID & 0xff;
+
+    data[8] = mLastNTPTime >> (64 - 8);
+    data[9] = (mLastNTPTime >> (64 - 16)) & 0xff;
+    data[10] = (mLastNTPTime >> (64 - 24)) & 0xff;
+    data[11] = (mLastNTPTime >> 32) & 0xff;
+    data[12] = (mLastNTPTime >> 24) & 0xff;
+    data[13] = (mLastNTPTime >> 16) & 0xff;
+    data[14] = (mLastNTPTime >> 8) & 0xff;
+    data[15] = mLastNTPTime & 0xff;
+
+    data[16] = (mLastRTPTime >> 24) & 0xff;
+    data[17] = (mLastRTPTime >> 16) & 0xff;
+    data[18] = (mLastRTPTime >> 8) & 0xff;
+    data[19] = mLastRTPTime & 0xff;
+
+    data[20] = mNumRTPSent >> 24;
+    data[21] = (mNumRTPSent >> 16) & 0xff;
+    data[22] = (mNumRTPSent >> 8) & 0xff;
+    data[23] = mNumRTPSent & 0xff;
+
+    data[24] = mNumRTPOctetsSent >> 24;
+    data[25] = (mNumRTPOctetsSent >> 16) & 0xff;
+    data[26] = (mNumRTPOctetsSent >> 8) & 0xff;
+    data[27] = mNumRTPOctetsSent & 0xff;
+
+    buffer->setRange(buffer->offset(), buffer->size() + 28);
+}
+
+void WifiDisplaySource::PlaybackSession::addSDES(const sp<ABuffer> &buffer) {
+    uint8_t *data = buffer->data() + buffer->size();
+    data[0] = 0x80 | 1;
+    data[1] = 202;  // SDES
+    data[4] = kSourceID >> 24;
+    data[5] = (kSourceID >> 16) & 0xff;
+    data[6] = (kSourceID >> 8) & 0xff;
+    data[7] = kSourceID & 0xff;
+
+    size_t offset = 8;
+
+    data[offset++] = 1;  // CNAME
+
+    static const char *kCNAME = "someone@somewhere";
+    data[offset++] = strlen(kCNAME);
+
+    memcpy(&data[offset], kCNAME, strlen(kCNAME));
+    offset += strlen(kCNAME);
+
+    data[offset++] = 7;  // NOTE
+
+    static const char *kNOTE = "Hell's frozen over.";
+    data[offset++] = strlen(kNOTE);
+
+    memcpy(&data[offset], kNOTE, strlen(kNOTE));
+    offset += strlen(kNOTE);
+
+    data[offset++] = 0;
+
+    if ((offset % 4) > 0) {
+        size_t count = 4 - (offset % 4);
+        switch (count) {
+            case 3:
+                data[offset++] = 0;
+            case 2:
+                data[offset++] = 0;
+            case 1:
+                data[offset++] = 0;
+        }
+    }
+
+    size_t numWords = (offset / 4) - 1;
+    data[2] = numWords >> 8;
+    data[3] = numWords & 0xff;
+
+    buffer->setRange(buffer->offset(), buffer->size() + offset);
+}
+
+// static
+uint64_t WifiDisplaySource::PlaybackSession::GetNowNTP() {
+    uint64_t nowUs = ALooper::GetNowUs();
+
+    nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll;
+
+    uint64_t hi = nowUs / 1000000ll;
+    uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll;
+
+    return (hi << 32) | lo;
+}
+
+void WifiDisplaySource::PlaybackSession::onSendSR() {
+    sp<ABuffer> buffer = new ABuffer(1500);
+    buffer->setRange(0, 0);
+
+    addSR(buffer);
+    addSDES(buffer);
+
+    if (mUseInterleavedTCP) {
+        sp<AMessage> notify = mNotify->dup();
+        notify->setInt32("what", kWhatBinaryData);
+        notify->setInt32("channel", mRTCPChannel);
+        notify->setBuffer("data", buffer);
+        notify->post();
+    } else {
+        mNetSession->sendRequest(
+                mRTCPSessionID, buffer->data(), buffer->size());
+    }
+
+    ++mNumSRsSent;
+}
+
+ssize_t WifiDisplaySource::PlaybackSession::appendTSData(
+        const void *data, size_t size, bool timeDiscontinuity, bool flush) {
+    CHECK_EQ(size, 188);
+
+    CHECK_LE(mTSQueue->size() + size, mTSQueue->capacity());
+
+    memcpy(mTSQueue->data() + mTSQueue->size(), data, size);
+    mTSQueue->setRange(0, mTSQueue->size() + size);
+
+    if (flush || mTSQueue->size() == mTSQueue->capacity()) {
+        // flush
+
+        int64_t nowUs = ALooper::GetNowUs();
+        if (mFirstPacketTimeUs < 0ll) {
+            mFirstPacketTimeUs = nowUs;
+        }
+
+        // 90kHz time scale
+        uint32_t rtpTime = ((nowUs - mFirstPacketTimeUs) * 9ll) / 100ll;
+
+        uint8_t *rtp = mTSQueue->data();
+        rtp[0] = 0x80;
+        rtp[1] = 33 | (timeDiscontinuity ? (1 << 7) : 0);  // M-bit
+        rtp[2] = (mRTPSeqNo >> 8) & 0xff;
+        rtp[3] = mRTPSeqNo & 0xff;
+        rtp[4] = rtpTime >> 24;
+        rtp[5] = (rtpTime >> 16) & 0xff;
+        rtp[6] = (rtpTime >> 8) & 0xff;
+        rtp[7] = rtpTime & 0xff;
+        rtp[8] = kSourceID >> 24;
+        rtp[9] = (kSourceID >> 16) & 0xff;
+        rtp[10] = (kSourceID >> 8) & 0xff;
+        rtp[11] = kSourceID & 0xff;
+
+        ++mRTPSeqNo;
+        ++mNumRTPSent;
+        mNumRTPOctetsSent += mTSQueue->size() - 12;
+
+        mLastRTPTime = rtpTime;
+        mLastNTPTime = GetNowNTP();
+
+        if (mUseInterleavedTCP) {
+            sp<AMessage> notify = mNotify->dup();
+            notify->setInt32("what", kWhatBinaryData);
+
+            sp<ABuffer> data = new ABuffer(mTSQueue->size());
+            memcpy(data->data(), rtp, mTSQueue->size());
+
+            notify->setInt32("channel", mRTPChannel);
+            notify->setBuffer("data", data);
+            notify->post();
+        } else {
+            mNetSession->sendRequest(
+                    mRTPSessionID, rtp, mTSQueue->size());
+        }
+
+        mTSQueue->setInt32Data(mRTPSeqNo - 1);
+        mHistory.push_back(mTSQueue);
+        ++mHistoryLength;
+
+        if (mHistoryLength > kMaxHistoryLength) {
+            mTSQueue = *mHistory.begin();
+            mHistory.erase(mHistory.begin());
+
+            --mHistoryLength;
+        } else {
+            mTSQueue = new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188);
+        }
+
+        mTSQueue->setRange(0, 12);
+    }
+
+    return size;
+}
+
+status_t WifiDisplaySource::PlaybackSession::parseRTCP(
+        const sp<ABuffer> &buffer) {
+    const uint8_t *data = buffer->data();
+    size_t size = buffer->size();
+
+    while (size > 0) {
+        if (size < 8) {
+            // Too short to be a valid RTCP header
+            return ERROR_MALFORMED;
+        }
+
+        if ((data[0] >> 6) != 2) {
+            // Unsupported version.
+            return ERROR_UNSUPPORTED;
+        }
+
+        if (data[0] & 0x20) {
+            // Padding present.
+
+            size_t paddingLength = data[size - 1];
+
+            if (paddingLength + 12 > size) {
+                // If we removed this much padding we'd end up with something
+                // that's too short to be a valid RTP header.
+                return ERROR_MALFORMED;
+            }
+
+            size -= paddingLength;
+        }
+
+        size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4;
+
+        if (size < headerLength) {
+            // Only received a partial packet?
+            return ERROR_MALFORMED;
+        }
+
+        switch (data[1]) {
+            case 200:
+            case 201:  // RR
+            case 202:  // SDES
+            case 203:
+            case 204:  // APP
+                break;
+
+            case 205:  // TSFB (transport layer specific feedback)
+                parseTSFB(data, headerLength);
+                break;
+
+            case 206:  // PSFB (payload specific feedback)
+                hexdump(data, headerLength);
+                break;
+
+            default:
+            {
+                ALOGW("Unknown RTCP packet type %u of size %d",
+                     (unsigned)data[1], headerLength);
+                break;
+            }
+        }
+
+        data += headerLength;
+        size -= headerLength;
+    }
+
+    return OK;
+}
+
+status_t WifiDisplaySource::PlaybackSession::parseTSFB(
+        const uint8_t *data, size_t size) {
+    if ((data[0] & 0x1f) != 1) {
+        return ERROR_UNSUPPORTED;  // We only support NACK for now.
+    }
+
+    uint32_t srcId = U32_AT(&data[8]);
+    if (srcId != kSourceID) {
+        return ERROR_MALFORMED;
+    }
+
+    for (size_t i = 12; i < size; i += 4) {
+        uint16_t seqNo = U16_AT(&data[i]);
+        uint16_t blp = U16_AT(&data[i + 2]);
+
+        List<sp<ABuffer> >::iterator it = mHistory.begin();
+        bool found = false;
+        while (it != mHistory.end()) {
+            const sp<ABuffer> &buffer = *it;
+
+            uint16_t bufferSeqNo = buffer->int32Data() & 0xffff;
+
+            if (bufferSeqNo == seqNo) {
+                mNetSession->sendRequest(
+                        mRTPSessionID, buffer->data(), buffer->size());
+
+                found = true;
+                break;
+            }
+
+            ++it;
+        }
+
+        if (found) {
+            ALOGI("retransmitting seqNo %d", seqNo);
+        } else {
+            ALOGI("seqNo %d no longer available", seqNo);
+        }
+    }
+
+    return OK;
+}
+
+}  // namespace android
+
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.h b/media/libstagefright/wifi-display/source/PlaybackSession.h
new file mode 100644
index 0000000..d256fc4
--- /dev/null
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2012, 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 PLAYBACK_SESSION_H_
+
+#define PLAYBACK_SESSION_H_
+
+#include "WifiDisplaySource.h"
+
+namespace android {
+
+struct ABuffer;
+struct Serializer;
+struct TSPacketizer;
+
+// Encapsulates the state of an RTP/RTCP session in the context of wifi
+// display.
+struct WifiDisplaySource::PlaybackSession : public AHandler {
+    PlaybackSession(
+            const sp<ANetworkSession> &netSession, const sp<AMessage> &notify);
+
+    status_t init(
+            const char *clientIP, int32_t clientRtp, int32_t clientRtcp,
+            bool useInterleavedTCP);
+
+    int32_t getRTPPort() const;
+
+    int64_t getLastLifesignUs() const;
+    void updateLiveness();
+
+    status_t play();
+    status_t pause();
+
+    enum {
+        kWhatSessionDead,
+        kWhatBinaryData,
+    };
+
+protected:
+    virtual void onMessageReceived(const sp<AMessage> &msg);
+    virtual ~PlaybackSession();
+
+private:
+    struct Track;
+
+    enum {
+        kWhatSendSR,
+        kWhatRTPNotify,
+        kWhatRTCPNotify,
+        kWhatSerializerNotify,
+        kWhatConverterNotify,
+        kWhatUpdateSurface,
+    };
+
+    static const int64_t kSendSRIntervalUs = 10000000ll;
+    static const uint32_t kSourceID = 0xdeadbeef;
+    static const size_t kMaxHistoryLength = 128;
+
+    sp<ANetworkSession> mNetSession;
+    sp<AMessage> mNotify;
+
+    int64_t mLastLifesignUs;
+
+    sp<ALooper> mSerializerLooper;
+    sp<Serializer> mSerializer;
+    sp<TSPacketizer> mPacketizer;
+    sp<ALooper> mCodecLooper;
+
+    KeyedVector<size_t, sp<Track> > mTracks;
+
+    sp<ABuffer> mTSQueue;
+    int64_t mPrevTimeUs;
+
+    bool mUseInterleavedTCP;
+
+    // in TCP mode
+    int32_t mRTPChannel;
+    int32_t mRTCPChannel;
+
+    // in UDP mode
+    int32_t mRTPPort;
+    int32_t mRTPSessionID;
+    int32_t mRTCPSessionID;
+
+
+    uint32_t mRTPSeqNo;
+
+    uint64_t mLastNTPTime;
+    uint32_t mLastRTPTime;
+    uint32_t mNumRTPSent;
+    uint32_t mNumRTPOctetsSent;
+    uint32_t mNumSRsSent;
+
+    bool mSendSRPending;
+
+    int64_t mFirstPacketTimeUs;
+
+    List<sp<ABuffer> > mHistory;
+    size_t mHistoryLength;
+
+    void onSendSR();
+    void addSR(const sp<ABuffer> &buffer);
+    void addSDES(const sp<ABuffer> &buffer);
+    static uint64_t GetNowNTP();
+
+    status_t setupPacketizer();
+
+    ssize_t appendTSData(
+            const void *data, size_t size, bool timeDiscontinuity, bool flush);
+
+    void scheduleSendSR();
+
+    status_t parseRTCP(const sp<ABuffer> &buffer);
+    status_t parseTSFB(const uint8_t *data, size_t size);
+
+    DISALLOW_EVIL_CONSTRUCTORS(PlaybackSession);
+};
+
+}  // namespace android
+
+#endif  // PLAYBACK_SESSION_H_
+
diff --git a/media/libstagefright/wifi-display/source/RepeaterSource.cpp b/media/libstagefright/wifi-display/source/RepeaterSource.cpp
new file mode 100644
index 0000000..8af4fdf
--- /dev/null
+++ b/media/libstagefright/wifi-display/source/RepeaterSource.cpp
@@ -0,0 +1,140 @@
+//#define LOG_NDEBUG 0
+#define LOG_TAG "RepeaterSource"
+#include <utils/Log.h>
+
+#include "RepeaterSource.h"
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MetaData.h>
+
+namespace android {
+
+RepeaterSource::RepeaterSource(const sp<MediaSource> &source, double rateHz)
+    : mSource(source),
+      mRateHz(rateHz),
+      mBuffer(NULL),
+      mResult(OK),
+      mStartTimeUs(-1ll),
+      mFrameCount(0) {
+}
+
+RepeaterSource::~RepeaterSource() {
+    stop();
+}
+
+status_t RepeaterSource::start(MetaData *params) {
+    status_t err = mSource->start(params);
+
+    if (err != OK) {
+        return err;
+    }
+
+    mBuffer = NULL;
+    mResult = OK;
+    mStartTimeUs = -1ll;
+    mFrameCount = 0;
+
+    mLooper = new ALooper;
+    mLooper->start();
+
+    mReflector = new AHandlerReflector<RepeaterSource>(this);
+    mLooper->registerHandler(mReflector);
+
+    postRead();
+
+    return OK;
+}
+
+status_t RepeaterSource::stop() {
+    if (mLooper != NULL) {
+        mLooper->stop();
+        mLooper.clear();
+
+        mReflector.clear();
+    }
+
+    return mSource->stop();
+}
+
+sp<MetaData> RepeaterSource::getFormat() {
+    return mSource->getFormat();
+}
+
+status_t RepeaterSource::read(
+        MediaBuffer **buffer, const ReadOptions *options) {
+    int64_t seekTimeUs;
+    ReadOptions::SeekMode seekMode;
+    CHECK(options == NULL || !options->getSeekTo(&seekTimeUs, &seekMode));
+
+    int64_t bufferTimeUs = -1ll;
+
+    if (mStartTimeUs < 0ll) {
+        Mutex::Autolock autoLock(mLock);
+        while (mBuffer == NULL && mResult == OK) {
+            mCondition.wait(mLock);
+        }
+
+        mStartTimeUs = ALooper::GetNowUs();
+        bufferTimeUs = mStartTimeUs;
+    } else {
+        bufferTimeUs = mStartTimeUs + (mFrameCount * 1000000ll) / mRateHz;
+
+        int64_t nowUs = ALooper::GetNowUs();
+        int64_t delayUs = bufferTimeUs - nowUs;
+
+        if (delayUs > 0ll) {
+            usleep(delayUs);
+        }
+    }
+
+    Mutex::Autolock autoLock(mLock);
+    if (mResult != OK) {
+        CHECK(mBuffer == NULL);
+        return mResult;
+    }
+
+    mBuffer->add_ref();
+    *buffer = mBuffer;
+    (*buffer)->meta_data()->setInt64(kKeyTime, bufferTimeUs);
+
+    ++mFrameCount;
+
+    return OK;
+}
+
+void RepeaterSource::postRead() {
+    (new AMessage(kWhatRead, mReflector->id()))->post();
+}
+
+void RepeaterSource::onMessageReceived(const sp<AMessage> &msg) {
+    switch (msg->what()) {
+        case kWhatRead:
+        {
+            MediaBuffer *buffer;
+            status_t err = mSource->read(&buffer);
+
+            Mutex::Autolock autoLock(mLock);
+            if (mBuffer != NULL) {
+                mBuffer->release();
+                mBuffer = NULL;
+            }
+            mBuffer = buffer;
+            mResult = err;
+
+            mCondition.broadcast();
+
+            if (err == OK) {
+                postRead();
+            }
+            break;
+        }
+
+        default:
+            TRESPASS();
+    }
+}
+
+}  // namespace android
diff --git a/media/libstagefright/wifi-display/source/RepeaterSource.h b/media/libstagefright/wifi-display/source/RepeaterSource.h
new file mode 100644
index 0000000..31eb5cd
--- /dev/null
+++ b/media/libstagefright/wifi-display/source/RepeaterSource.h
@@ -0,0 +1,55 @@
+#ifndef REPEATER_SOURCE_H_
+
+#define REPEATER_SOURCE_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/AHandlerReflector.h>
+#include <media/stagefright/MediaSource.h>
+
+namespace android {
+
+// This MediaSource delivers frames at a constant rate by repeating buffers
+// if necessary.
+struct RepeaterSource : public MediaSource {
+    RepeaterSource(const sp<MediaSource> &source, double rateHz);
+
+    virtual status_t start(MetaData *params);
+    virtual status_t stop();
+    virtual sp<MetaData> getFormat();
+
+    virtual status_t read(
+            MediaBuffer **buffer, const ReadOptions *options);
+
+    void onMessageReceived(const sp<AMessage> &msg);
+
+protected:
+    virtual ~RepeaterSource();
+
+private:
+    enum {
+        kWhatRead,
+    };
+
+    Mutex mLock;
+    Condition mCondition;
+
+    sp<MediaSource> mSource;
+    double mRateHz;
+
+    sp<ALooper> mLooper;
+    sp<AHandlerReflector<RepeaterSource> > mReflector;
+
+    MediaBuffer *mBuffer;
+    status_t mResult;
+
+    int64_t mStartTimeUs;
+    int32_t mFrameCount;
+
+    void postRead();
+
+    DISALLOW_EVIL_CONSTRUCTORS(RepeaterSource);
+};
+
+}  // namespace android
+
+#endif // REPEATER_SOURCE_H_
diff --git a/media/libstagefright/wifi-display/source/Serializer.cpp b/media/libstagefright/wifi-display/source/Serializer.cpp
new file mode 100644
index 0000000..bd53fc8
--- /dev/null
+++ b/media/libstagefright/wifi-display/source/Serializer.cpp
@@ -0,0 +1,366 @@
+/*
+ * Copyright 2012, 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 "Serializer"
+#include <utils/Log.h>
+
+#include "Serializer.h"
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MetaData.h>
+
+namespace android {
+
+struct Serializer::Track : public RefBase {
+    Track(const sp<MediaSource> &source);
+
+    status_t start();
+    status_t stop();
+
+    void readBufferIfNecessary();
+
+    bool reachedEOS() const;
+    int64_t bufferTimeUs() const;
+
+    sp<ABuffer> drainBuffer();
+
+protected:
+    virtual ~Track();
+
+private:
+    sp<MediaSource> mSource;
+
+    bool mStarted;
+    status_t mFinalResult;
+    MediaBuffer *mBuffer;
+    int64_t mBufferTimeUs;
+
+    DISALLOW_EVIL_CONSTRUCTORS(Track);
+};
+
+Serializer::Track::Track(const sp<MediaSource> &source)
+    : mSource(source),
+      mStarted(false),
+      mFinalResult(OK),
+      mBuffer(NULL),
+      mBufferTimeUs(-1ll) {
+}
+
+Serializer::Track::~Track() {
+    stop();
+}
+
+status_t Serializer::Track::start() {
+    if (mStarted) {
+        return OK;
+    }
+
+    status_t err = mSource->start();
+
+    if (err == OK) {
+        mStarted = true;
+    }
+
+    return err;
+}
+
+status_t Serializer::Track::stop() {
+    if (!mStarted) {
+        return OK;
+    }
+
+    if (mBuffer != NULL) {
+        mBuffer->release();
+        mBuffer = NULL;
+
+        mBufferTimeUs = -1ll;
+    }
+
+    status_t err = mSource->stop();
+
+    mStarted = false;
+
+    return err;
+}
+
+void Serializer::Track::readBufferIfNecessary() {
+    if (mBuffer != NULL) {
+        return;
+    }
+
+    mFinalResult = mSource->read(&mBuffer);
+
+    if (mFinalResult != OK) {
+        ALOGI("read failed w/ err %d", mFinalResult);
+        return;
+    }
+
+    CHECK(mBuffer->meta_data()->findInt64(kKeyTime, &mBufferTimeUs));
+}
+
+bool Serializer::Track::reachedEOS() const {
+    return mFinalResult != OK;
+}
+
+int64_t Serializer::Track::bufferTimeUs() const {
+    return mBufferTimeUs;
+}
+
+sp<ABuffer> Serializer::Track::drainBuffer() {
+    sp<ABuffer> accessUnit = new ABuffer(mBuffer->range_length());
+
+    memcpy(accessUnit->data(),
+           (const uint8_t *)mBuffer->data() + mBuffer->range_offset(),
+           mBuffer->range_length());
+
+    accessUnit->meta()->setInt64("timeUs", mBufferTimeUs);
+    accessUnit->meta()->setPointer("mediaBuffer", mBuffer);
+
+    mBuffer = NULL;
+    mBufferTimeUs = -1ll;
+
+    return accessUnit;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+Serializer::Serializer(bool throttle, const sp<AMessage> &notify)
+    : mThrottle(throttle),
+      mNotify(notify),
+      mPollGeneration(0),
+      mStartTimeUs(-1ll) {
+}
+
+Serializer::~Serializer() {
+}
+
+status_t Serializer::postSynchronouslyAndReturnError(
+        const sp<AMessage> &msg) {
+    sp<AMessage> response;
+    status_t err = msg->postAndAwaitResponse(&response);
+
+    if (err != OK) {
+        return err;
+    }
+
+    if (!response->findInt32("err", &err)) {
+        err = OK;
+    }
+
+    return err;
+}
+
+ssize_t Serializer::addSource(const sp<MediaSource> &source) {
+    sp<AMessage> msg = new AMessage(kWhatAddSource, id());
+    msg->setPointer("source", source.get());
+
+    sp<AMessage> response;
+    status_t err = msg->postAndAwaitResponse(&response);
+
+    if (err != OK) {
+        return err;
+    }
+
+    if (!response->findInt32("err", &err)) {
+        size_t index;
+        CHECK(response->findSize("index", &index));
+
+        return index;
+    }
+
+    return err;
+}
+
+status_t Serializer::start() {
+    return postSynchronouslyAndReturnError(new AMessage(kWhatStart, id()));
+}
+
+status_t Serializer::stop() {
+    return postSynchronouslyAndReturnError(new AMessage(kWhatStop, id()));
+}
+
+void Serializer::onMessageReceived(const sp<AMessage> &msg) {
+    switch (msg->what()) {
+        case kWhatAddSource:
+        {
+            ssize_t index = onAddSource(msg);
+
+            sp<AMessage> response = new AMessage;
+
+            if (index < 0) {
+                response->setInt32("err", index);
+            } else {
+                response->setSize("index", index);
+            }
+
+            uint32_t replyID;
+            CHECK(msg->senderAwaitsResponse(&replyID));
+
+            response->postReply(replyID);
+            break;
+        }
+
+        case kWhatStart:
+        case kWhatStop:
+        {
+            status_t err = (msg->what() == kWhatStart) ? onStart() : onStop();
+
+            sp<AMessage> response = new AMessage;
+            response->setInt32("err", err);
+
+            uint32_t replyID;
+            CHECK(msg->senderAwaitsResponse(&replyID));
+
+            response->postReply(replyID);
+            break;
+        }
+
+        case kWhatPoll:
+        {
+            int32_t generation;
+            CHECK(msg->findInt32("generation", &generation));
+
+            if (generation != mPollGeneration) {
+                break;
+            }
+
+            int64_t delayUs = onPoll();
+            if (delayUs >= 0ll) {
+                schedulePoll(delayUs);
+            }
+            break;
+        }
+
+        default:
+            TRESPASS();
+    }
+}
+
+ssize_t Serializer::onAddSource(const sp<AMessage> &msg) {
+    void *obj;
+    CHECK(msg->findPointer("source", &obj));
+
+    sp<MediaSource> source = static_cast<MediaSource *>(obj);
+
+    sp<Track> track = new Track(source);
+    return mTracks.add(track);
+}
+
+status_t Serializer::onStart() {
+    status_t err = OK;
+    for (size_t i = 0; i < mTracks.size(); ++i) {
+        err = mTracks.itemAt(i)->start();
+
+        if (err != OK) {
+            break;
+        }
+    }
+
+    if (err == OK) {
+#if 0
+        schedulePoll();
+#else
+        // XXX the dongle doesn't appear to have setup the RTP connection
+        // fully at the time PLAY is called. We have to delay sending data
+        // for a little bit.
+        schedulePoll(500000ll);
+#endif
+    }
+
+    return err;
+}
+
+status_t Serializer::onStop() {
+    for (size_t i = 0; i < mTracks.size(); ++i) {
+        mTracks.itemAt(i)->stop();
+    }
+
+    cancelPoll();
+
+    return OK;
+}
+
+int64_t Serializer::onPoll() {
+    int64_t minTimeUs = -1ll;
+    ssize_t minTrackIndex = -1;
+
+    for (size_t i = 0; i < mTracks.size(); ++i) {
+        const sp<Track> &track = mTracks.itemAt(i);
+
+        track->readBufferIfNecessary();
+
+        if (!track->reachedEOS()) {
+            int64_t timeUs = track->bufferTimeUs();
+
+            if (minTrackIndex < 0 || timeUs < minTimeUs) {
+                minTimeUs = timeUs;
+                minTrackIndex = i;
+            }
+        }
+    }
+
+    if (minTrackIndex < 0) {
+        sp<AMessage> notify = mNotify->dup();
+        notify->setInt32("what", kWhatEOS);
+        notify->post();
+
+        return -1ll;
+    }
+
+    if (mThrottle) {
+        int64_t nowUs = ALooper::GetNowUs();
+
+        if (mStartTimeUs < 0ll) {
+            mStartTimeUs = nowUs;
+        }
+
+        int64_t lateByUs = nowUs - (minTimeUs + mStartTimeUs);
+
+        if (lateByUs < 0ll) {
+            // Too early
+            return -lateByUs;
+        }
+    }
+
+    sp<AMessage> notify = mNotify->dup();
+
+    notify->setInt32("what", kWhatAccessUnit);
+    notify->setSize("trackIndex", minTrackIndex);
+
+    notify->setBuffer(
+            "accessUnit", mTracks.itemAt(minTrackIndex)->drainBuffer());
+
+    notify->post();
+
+    return 0ll;
+}
+
+void Serializer::schedulePoll(int64_t delayUs) {
+    sp<AMessage> msg = new AMessage(kWhatPoll, id());
+    msg->setInt32("generation", mPollGeneration);
+    msg->post(delayUs);
+}
+
+void Serializer::cancelPoll() {
+    ++mPollGeneration;
+}
+
+}  // namespace android
diff --git a/media/libstagefright/wifi-display/source/Serializer.h b/media/libstagefright/wifi-display/source/Serializer.h
new file mode 100644
index 0000000..07950fa
--- /dev/null
+++ b/media/libstagefright/wifi-display/source/Serializer.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2012, 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 SERIALIZER_H_
+
+#define SERIALIZER_H_
+
+#include <media/stagefright/foundation/AHandler.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+struct AMessage;
+struct MediaSource;
+
+// After adding a number of MediaSource objects and starting the Serializer,
+// it'll emit their access units in order of increasing timestamps.
+struct Serializer : public AHandler {
+    enum {
+        kWhatEOS,
+        kWhatAccessUnit
+    };
+
+    // In throttled operation, data is emitted at a pace corresponding
+    // to the incoming media timestamps.
+    Serializer(bool throttle, const sp<AMessage> &notify);
+
+    ssize_t addSource(const sp<MediaSource> &source);
+
+    status_t start();
+    status_t stop();
+
+protected:
+    virtual void onMessageReceived(const sp<AMessage> &what);
+    virtual ~Serializer();
+
+private:
+    enum {
+        kWhatAddSource,
+        kWhatStart,
+        kWhatStop,
+        kWhatPoll
+    };
+
+    struct Track;
+
+    bool mThrottle;
+    sp<AMessage> mNotify;
+    Vector<sp<Track> > mTracks;
+
+    int32_t mPollGeneration;
+
+    int64_t mStartTimeUs;
+
+    status_t postSynchronouslyAndReturnError(const sp<AMessage> &msg);
+
+    ssize_t onAddSource(const sp<AMessage> &msg);
+    status_t onStart();
+    status_t onStop();
+    int64_t onPoll();
+
+    void schedulePoll(int64_t delayUs = 0ll);
+    void cancelPoll();
+
+    DISALLOW_EVIL_CONSTRUCTORS(Serializer);
+};
+
+}  // namespace android
+
+#endif  // SERIALIZER_H_
+
diff --git a/media/libstagefright/wifi-display/source/TSPacketizer.cpp b/media/libstagefright/wifi-display/source/TSPacketizer.cpp
new file mode 100644
index 0000000..b9a3e9b
--- /dev/null
+++ b/media/libstagefright/wifi-display/source/TSPacketizer.cpp
@@ -0,0 +1,694 @@
+/*
+ * Copyright 2012, 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 "TSPacketizer"
+#include <utils/Log.h>
+
+#include "TSPacketizer.h"
+#include "include/avc_utils.h"
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/hexdump.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
+
+#include <arpa/inet.h>
+
+namespace android {
+
+struct TSPacketizer::Track : public RefBase {
+    Track(const sp<AMessage> &format,
+          unsigned PID, unsigned streamType, unsigned streamID);
+
+    unsigned PID() const;
+    unsigned streamType() const;
+    unsigned streamID() const;
+
+    // Returns the previous value.
+    unsigned incrementContinuityCounter();
+
+    bool isAudio() const;
+    bool isVideo() const;
+
+    bool isH264() const;
+    bool lacksADTSHeader() const;
+
+    sp<ABuffer> prependCSD(const sp<ABuffer> &accessUnit) const;
+    sp<ABuffer> prependADTSHeader(const sp<ABuffer> &accessUnit) const;
+
+protected:
+    virtual ~Track();
+
+private:
+    sp<AMessage> mFormat;
+
+    unsigned mPID;
+    unsigned mStreamType;
+    unsigned mStreamID;
+    unsigned mContinuityCounter;
+
+    AString mMIME;
+    Vector<sp<ABuffer> > mCSD;
+
+    DISALLOW_EVIL_CONSTRUCTORS(Track);
+};
+
+TSPacketizer::Track::Track(
+        const sp<AMessage> &format,
+        unsigned PID, unsigned streamType, unsigned streamID)
+    : mFormat(format),
+      mPID(PID),
+      mStreamType(streamType),
+      mStreamID(streamID),
+      mContinuityCounter(0) {
+    CHECK(format->findString("mime", &mMIME));
+
+    if (!strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)
+            || !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
+        for (size_t i = 0;; ++i) {
+            sp<ABuffer> csd;
+            if (!format->findBuffer(StringPrintf("csd-%d", i).c_str(), &csd)) {
+                break;
+            }
+
+            mCSD.push(csd);
+        }
+    }
+}
+
+TSPacketizer::Track::~Track() {
+}
+
+unsigned TSPacketizer::Track::PID() const {
+    return mPID;
+}
+
+unsigned TSPacketizer::Track::streamType() const {
+    return mStreamType;
+}
+
+unsigned TSPacketizer::Track::streamID() const {
+    return mStreamID;
+}
+
+unsigned TSPacketizer::Track::incrementContinuityCounter() {
+    unsigned prevCounter = mContinuityCounter;
+
+    if (++mContinuityCounter == 16) {
+        mContinuityCounter = 0;
+    }
+
+    return prevCounter;
+}
+
+bool TSPacketizer::Track::isAudio() const {
+    return !strncasecmp("audio/", mMIME.c_str(), 6);
+}
+
+bool TSPacketizer::Track::isVideo() const {
+    return !strncasecmp("video/", mMIME.c_str(), 6);
+}
+
+bool TSPacketizer::Track::isH264() const {
+    return !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_VIDEO_AVC);
+}
+
+bool TSPacketizer::Track::lacksADTSHeader() const {
+    if (strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
+        return false;
+    }
+
+    int32_t isADTS;
+    if (mFormat->findInt32("is-adts", &isADTS) && isADTS != 0) {
+        return false;
+    }
+
+    return true;
+}
+
+sp<ABuffer> TSPacketizer::Track::prependCSD(
+        const sp<ABuffer> &accessUnit) const {
+    size_t size = 0;
+    for (size_t i = 0; i < mCSD.size(); ++i) {
+        size += mCSD.itemAt(i)->size();
+    }
+
+    sp<ABuffer> dup = new ABuffer(accessUnit->size() + size);
+    size_t offset = 0;
+    for (size_t i = 0; i < mCSD.size(); ++i) {
+        const sp<ABuffer> &csd = mCSD.itemAt(i);
+
+        memcpy(dup->data() + offset, csd->data(), csd->size());
+        offset += csd->size();
+    }
+
+    memcpy(dup->data() + offset, accessUnit->data(), accessUnit->size());
+
+    return dup;
+}
+
+sp<ABuffer> TSPacketizer::Track::prependADTSHeader(
+        const sp<ABuffer> &accessUnit) const {
+    CHECK_EQ(mCSD.size(), 1u);
+
+    const uint8_t *codec_specific_data = mCSD.itemAt(0)->data();
+
+    const uint32_t aac_frame_length = accessUnit->size() + 7;
+
+    sp<ABuffer> dup = new ABuffer(aac_frame_length);
+
+    unsigned profile = (codec_specific_data[0] >> 3) - 1;
+
+    unsigned sampling_freq_index =
+        ((codec_specific_data[0] & 7) << 1)
+        | (codec_specific_data[1] >> 7);
+
+    unsigned channel_configuration =
+        (codec_specific_data[1] >> 3) & 0x0f;
+
+    uint8_t *ptr = dup->data();
+
+    *ptr++ = 0xff;
+    *ptr++ = 0xf1;  // b11110001, ID=0, layer=0, protection_absent=1
+
+    *ptr++ =
+        profile << 6
+        | sampling_freq_index << 2
+        | ((channel_configuration >> 2) & 1);  // private_bit=0
+
+    // original_copy=0, home=0, copyright_id_bit=0, copyright_id_start=0
+    *ptr++ =
+        (channel_configuration & 3) << 6
+        | aac_frame_length >> 11;
+    *ptr++ = (aac_frame_length >> 3) & 0xff;
+    *ptr++ = (aac_frame_length & 7) << 5;
+
+    // adts_buffer_fullness=0, number_of_raw_data_blocks_in_frame=0
+    *ptr++ = 0;
+
+    memcpy(ptr, accessUnit->data(), accessUnit->size());
+
+    return dup;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+TSPacketizer::TSPacketizer()
+    : mPATContinuityCounter(0),
+      mPMTContinuityCounter(0) {
+    initCrcTable();
+}
+
+TSPacketizer::~TSPacketizer() {
+}
+
+ssize_t TSPacketizer::addTrack(const sp<AMessage> &format) {
+    AString mime;
+    CHECK(format->findString("mime", &mime));
+
+    unsigned PIDStart;
+    bool isVideo = !strncasecmp("video/", mime.c_str(), 6);
+    bool isAudio = !strncasecmp("audio/", mime.c_str(), 6);
+
+    if (isVideo) {
+        PIDStart = 0x1011;
+    } else if (isAudio) {
+        PIDStart = 0x1100;
+    } else {
+        return ERROR_UNSUPPORTED;
+    }
+
+    unsigned streamType;
+    unsigned streamIDStart;
+    unsigned streamIDStop;
+
+    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
+        streamType = 0x1b;
+        streamIDStart = 0xe0;
+        streamIDStop = 0xef;
+    } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
+        streamType = 0x0f;
+        streamIDStart = 0xc0;
+        streamIDStop = 0xdf;
+    } else {
+        return ERROR_UNSUPPORTED;
+    }
+
+    size_t numTracksOfThisType = 0;
+    unsigned PID = PIDStart;
+
+    for (size_t i = 0; i < mTracks.size(); ++i) {
+        const sp<Track> &track = mTracks.itemAt(i);
+
+        if (track->streamType() == streamType) {
+            ++numTracksOfThisType;
+        }
+
+        if ((isAudio && track->isAudio()) || (isVideo && track->isVideo())) {
+            ++PID;
+        }
+    }
+
+    unsigned streamID = streamIDStart + numTracksOfThisType;
+    if (streamID > streamIDStop) {
+        return -ERANGE;
+    }
+
+    sp<Track> track = new Track(format, PID, streamType, streamID);
+    return mTracks.add(track);
+}
+
+status_t TSPacketizer::packetize(
+        size_t trackIndex,
+        const sp<ABuffer> &_accessUnit,
+        sp<ABuffer> *packets,
+        uint32_t flags) {
+    sp<ABuffer> accessUnit = _accessUnit;
+
+    packets->clear();
+
+    if (trackIndex >= mTracks.size()) {
+        return -ERANGE;
+    }
+
+    int64_t timeUs;
+    CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
+
+    const sp<Track> &track = mTracks.itemAt(trackIndex);
+
+    if (track->isH264()) {
+        if (IsIDR(accessUnit)) {
+            // prepend codec specific data, i.e. SPS and PPS.
+            accessUnit = track->prependCSD(accessUnit);
+        }
+    } else if (track->lacksADTSHeader()) {
+        accessUnit = track->prependADTSHeader(accessUnit);
+    }
+
+    // 0x47
+    // transport_error_indicator = b0
+    // payload_unit_start_indicator = b1
+    // transport_priority = b0
+    // PID
+    // transport_scrambling_control = b00
+    // adaptation_field_control = b??
+    // continuity_counter = b????
+    // -- payload follows
+    // packet_startcode_prefix = 0x000001
+    // stream_id
+    // PES_packet_length = 0x????
+    // reserved = b10
+    // PES_scrambling_control = b00
+    // PES_priority = b0
+    // data_alignment_indicator = b1
+    // copyright = b0
+    // original_or_copy = b0
+    // PTS_DTS_flags = b10  (PTS only)
+    // ESCR_flag = b0
+    // ES_rate_flag = b0
+    // DSM_trick_mode_flag = b0
+    // additional_copy_info_flag = b0
+    // PES_CRC_flag = b0
+    // PES_extension_flag = b0
+    // PES_header_data_length = 0x05
+    // reserved = b0010 (PTS)
+    // PTS[32..30] = b???
+    // reserved = b1
+    // PTS[29..15] = b??? ???? ???? ???? (15 bits)
+    // reserved = b1
+    // PTS[14..0] = b??? ???? ???? ???? (15 bits)
+    // reserved = b1
+    // the first fragment of "buffer" follows
+
+    size_t numTSPackets;
+    if (accessUnit->size() <= 170) {
+        numTSPackets = 1;
+    } else {
+        numTSPackets = 1 + ((accessUnit->size() - 170) + 183) / 184;
+    }
+
+    if (flags & EMIT_PAT_AND_PMT) {
+        numTSPackets += 2;
+    }
+
+    if (flags & EMIT_PCR) {
+        ++numTSPackets;
+    }
+
+    sp<ABuffer> buffer = new ABuffer(numTSPackets * 188);
+    uint8_t *packetDataStart = buffer->data();
+
+    if (flags & EMIT_PAT_AND_PMT) {
+        // Program Association Table (PAT):
+        // 0x47
+        // transport_error_indicator = b0
+        // payload_unit_start_indicator = b1
+        // transport_priority = b0
+        // PID = b0000000000000 (13 bits)
+        // transport_scrambling_control = b00
+        // adaptation_field_control = b01 (no adaptation field, payload only)
+        // continuity_counter = b????
+        // skip = 0x00
+        // --- payload follows
+        // table_id = 0x00
+        // section_syntax_indicator = b1
+        // must_be_zero = b0
+        // reserved = b11
+        // section_length = 0x00d
+        // transport_stream_id = 0x0000
+        // reserved = b11
+        // version_number = b00001
+        // current_next_indicator = b1
+        // section_number = 0x00
+        // last_section_number = 0x00
+        //   one program follows:
+        //   program_number = 0x0001
+        //   reserved = b111
+        //   program_map_PID = kPID_PMT (13 bits!)
+        // CRC = 0x????????
+
+        if (++mPATContinuityCounter == 16) {
+            mPATContinuityCounter = 0;
+        }
+
+        uint8_t *ptr = packetDataStart;
+        *ptr++ = 0x47;
+        *ptr++ = 0x40;
+        *ptr++ = 0x00;
+        *ptr++ = 0x10 | mPATContinuityCounter;
+        *ptr++ = 0x00;
+
+        const uint8_t *crcDataStart = ptr;
+        *ptr++ = 0x00;
+        *ptr++ = 0xb0;
+        *ptr++ = 0x0d;
+        *ptr++ = 0x00;
+        *ptr++ = 0x00;
+        *ptr++ = 0xc3;
+        *ptr++ = 0x00;
+        *ptr++ = 0x00;
+        *ptr++ = 0x00;
+        *ptr++ = 0x01;
+        *ptr++ = 0xe0 | (kPID_PMT >> 8);
+        *ptr++ = kPID_PMT & 0xff;
+
+        CHECK_EQ(ptr - crcDataStart, 12);
+        uint32_t crc = htonl(crc32(crcDataStart, ptr - crcDataStart));
+        memcpy(ptr, &crc, 4);
+        ptr += 4;
+
+        size_t sizeLeft = packetDataStart + 188 - ptr;
+        memset(ptr, 0xff, sizeLeft);
+
+        packetDataStart += 188;
+
+        // Program Map (PMT):
+        // 0x47
+        // transport_error_indicator = b0
+        // payload_unit_start_indicator = b1
+        // transport_priority = b0
+        // PID = kPID_PMT (13 bits)
+        // transport_scrambling_control = b00
+        // adaptation_field_control = b01 (no adaptation field, payload only)
+        // continuity_counter = b????
+        // skip = 0x00
+        // -- payload follows
+        // table_id = 0x02
+        // section_syntax_indicator = b1
+        // must_be_zero = b0
+        // reserved = b11
+        // section_length = 0x???
+        // program_number = 0x0001
+        // reserved = b11
+        // version_number = b00001
+        // current_next_indicator = b1
+        // section_number = 0x00
+        // last_section_number = 0x00
+        // reserved = b111
+        // PCR_PID = kPCR_PID (13 bits)
+        // reserved = b1111
+        // program_info_length = 0x000
+        //   one or more elementary stream descriptions follow:
+        //   stream_type = 0x??
+        //   reserved = b111
+        //   elementary_PID = b? ???? ???? ???? (13 bits)
+        //   reserved = b1111
+        //   ES_info_length = 0x000
+        // CRC = 0x????????
+
+        if (++mPMTContinuityCounter == 16) {
+            mPMTContinuityCounter = 0;
+        }
+
+        size_t section_length = 5 * mTracks.size() + 4 + 9;
+
+        ptr = packetDataStart;
+        *ptr++ = 0x47;
+        *ptr++ = 0x40 | (kPID_PMT >> 8);
+        *ptr++ = kPID_PMT & 0xff;
+        *ptr++ = 0x10 | mPMTContinuityCounter;
+        *ptr++ = 0x00;
+
+        crcDataStart = ptr;
+        *ptr++ = 0x02;
+        *ptr++ = 0xb0 | (section_length >> 8);
+        *ptr++ = section_length & 0xff;
+        *ptr++ = 0x00;
+        *ptr++ = 0x01;
+        *ptr++ = 0xc3;
+        *ptr++ = 0x00;
+        *ptr++ = 0x00;
+        *ptr++ = 0xe0 | (kPID_PCR >> 8);
+        *ptr++ = kPID_PCR & 0xff;
+        *ptr++ = 0xf0;
+        *ptr++ = 0x00;
+
+        for (size_t i = 0; i < mTracks.size(); ++i) {
+            const sp<Track> &track = mTracks.itemAt(i);
+
+            *ptr++ = track->streamType();
+            *ptr++ = 0xe0 | (track->PID() >> 8);
+            *ptr++ = track->PID() & 0xff;
+            *ptr++ = 0xf0;
+            *ptr++ = 0x00;
+        }
+
+        CHECK_EQ(ptr - crcDataStart, 12 + mTracks.size() * 5);
+        crc = htonl(crc32(crcDataStart, ptr - crcDataStart));
+        memcpy(ptr, &crc, 4);
+        ptr += 4;
+
+        sizeLeft = packetDataStart + 188 - ptr;
+        memset(ptr, 0xff, sizeLeft);
+
+        packetDataStart += 188;
+    }
+
+    if (flags & EMIT_PCR) {
+        // PCR stream
+        // 0x47
+        // transport_error_indicator = b0
+        // payload_unit_start_indicator = b1
+        // transport_priority = b0
+        // PID = kPCR_PID (13 bits)
+        // transport_scrambling_control = b00
+        // adaptation_field_control = b10 (adaptation field only, no payload)
+        // continuity_counter = b0000 (does not increment)
+        // adaptation_field_length = 183
+        // discontinuity_indicator = b0
+        // random_access_indicator = b0
+        // elementary_stream_priority_indicator = b0
+        // PCR_flag = b1
+        // OPCR_flag = b0
+        // splicing_point_flag = b0
+        // transport_private_data_flag = b0
+        // adaptation_field_extension_flag = b0
+        // program_clock_reference_base = b?????????????????????????????????
+        // reserved = b111111
+        // program_clock_reference_extension = b?????????
+
+#if 0
+        int64_t nowUs = ALooper::GetNowUs();
+#else
+        int64_t nowUs = timeUs;
+#endif
+
+        uint64_t PCR = nowUs * 27;  // PCR based on a 27MHz clock
+        uint64_t PCR_base = PCR / 300;
+        uint32_t PCR_ext = PCR % 300;
+
+        uint8_t *ptr = packetDataStart;
+        *ptr++ = 0x47;
+        *ptr++ = 0x40 | (kPID_PCR >> 8);
+        *ptr++ = kPID_PCR & 0xff;
+        *ptr++ = 0x20;
+        *ptr++ = 0xb7;  // adaptation_field_length
+        *ptr++ = 0x10;
+        *ptr++ = (PCR_base >> 25) & 0xff;
+        *ptr++ = (PCR_base >> 17) & 0xff;
+        *ptr++ = (PCR_base >> 9) & 0xff;
+        *ptr++ = ((PCR_base & 1) << 7) | 0x7e | ((PCR_ext >> 8) & 1);
+        *ptr++ = (PCR_ext & 0xff);
+
+        size_t sizeLeft = packetDataStart + 188 - ptr;
+        memset(ptr, 0xff, sizeLeft);
+
+        packetDataStart += 188;
+    }
+
+    uint32_t PTS = (timeUs * 9ll) / 100ll;
+
+    size_t PES_packet_length = accessUnit->size() + 8;
+    bool padding = (accessUnit->size() < (188 - 18));
+
+    if (PES_packet_length >= 65536) {
+        // This really should only happen for video.
+        CHECK(track->isVideo());
+
+        // It's valid to set this to 0 for video according to the specs.
+        PES_packet_length = 0;
+    }
+
+    uint8_t *ptr = packetDataStart;
+    *ptr++ = 0x47;
+    *ptr++ = 0x40 | (track->PID() >> 8);
+    *ptr++ = track->PID() & 0xff;
+    *ptr++ = (padding ? 0x30 : 0x10) | track->incrementContinuityCounter();
+
+    if (padding) {
+        size_t paddingSize = 188 - 18 - accessUnit->size();
+        *ptr++ = paddingSize - 1;
+        if (paddingSize >= 2) {
+            *ptr++ = 0x00;
+            memset(ptr, 0xff, paddingSize - 2);
+            ptr += paddingSize - 2;
+        }
+    }
+
+    *ptr++ = 0x00;
+    *ptr++ = 0x00;
+    *ptr++ = 0x01;
+    *ptr++ = track->streamID();
+    *ptr++ = PES_packet_length >> 8;
+    *ptr++ = PES_packet_length & 0xff;
+    *ptr++ = 0x84;
+    *ptr++ = 0x80;
+    *ptr++ = 0x05;
+    *ptr++ = 0x20 | (((PTS >> 30) & 7) << 1) | 1;
+    *ptr++ = (PTS >> 22) & 0xff;
+    *ptr++ = (((PTS >> 15) & 0x7f) << 1) | 1;
+    *ptr++ = (PTS >> 7) & 0xff;
+    *ptr++ = ((PTS & 0x7f) << 1) | 1;
+
+    // 18 bytes of TS/PES header leave 188 - 18 = 170 bytes for the payload
+
+    size_t sizeLeft = packetDataStart + 188 - ptr;
+    size_t copy = accessUnit->size();
+    if (copy > sizeLeft) {
+        copy = sizeLeft;
+    }
+
+    memcpy(ptr, accessUnit->data(), copy);
+    ptr += copy;
+    CHECK_EQ(sizeLeft, copy);
+    memset(ptr, 0xff, sizeLeft - copy);
+
+    packetDataStart += 188;
+
+    size_t offset = copy;
+    while (offset < accessUnit->size()) {
+        bool padding = (accessUnit->size() - offset) < (188 - 4);
+
+        // for subsequent fragments of "buffer":
+        // 0x47
+        // transport_error_indicator = b0
+        // payload_unit_start_indicator = b0
+        // transport_priority = b0
+        // PID = b0 0001 1110 ???? (13 bits) [0x1e0 + 1 + sourceIndex]
+        // transport_scrambling_control = b00
+        // adaptation_field_control = b??
+        // continuity_counter = b????
+        // the fragment of "buffer" follows.
+
+        uint8_t *ptr = packetDataStart;
+        *ptr++ = 0x47;
+        *ptr++ = 0x00 | (track->PID() >> 8);
+        *ptr++ = track->PID() & 0xff;
+
+        *ptr++ = (padding ? 0x30 : 0x10) | track->incrementContinuityCounter();
+
+        if (padding) {
+            size_t paddingSize = 188 - 4 - (accessUnit->size() - offset);
+            *ptr++ = paddingSize - 1;
+            if (paddingSize >= 2) {
+                *ptr++ = 0x00;
+                memset(ptr, 0xff, paddingSize - 2);
+                ptr += paddingSize - 2;
+            }
+        }
+
+        // 4 bytes of TS header leave 188 - 4 = 184 bytes for the payload
+
+        size_t sizeLeft = packetDataStart + 188 - ptr;
+        size_t copy = accessUnit->size() - offset;
+        if (copy > sizeLeft) {
+            copy = sizeLeft;
+        }
+
+        memcpy(ptr, accessUnit->data() + offset, copy);
+        ptr += copy;
+        CHECK_EQ(sizeLeft, copy);
+        memset(ptr, 0xff, sizeLeft - copy);
+
+        offset += copy;
+        packetDataStart += 188;
+    }
+
+    CHECK(packetDataStart == buffer->data() + buffer->capacity());
+
+    *packets = buffer;
+
+    return OK;
+}
+
+void TSPacketizer::initCrcTable() {
+    uint32_t poly = 0x04C11DB7;
+
+    for (int i = 0; i < 256; i++) {
+        uint32_t crc = i << 24;
+        for (int j = 0; j < 8; j++) {
+            crc = (crc << 1) ^ ((crc & 0x80000000) ? (poly) : 0);
+        }
+        mCrcTable[i] = crc;
+    }
+}
+
+uint32_t TSPacketizer::crc32(const uint8_t *start, size_t size) const {
+    uint32_t crc = 0xFFFFFFFF;
+    const uint8_t *p;
+
+    for (p = start; p < start + size; ++p) {
+        crc = (crc << 8) ^ mCrcTable[((crc >> 24) ^ *p) & 0xFF];
+    }
+
+    return crc;
+}
+
+}  // namespace android
+
diff --git a/media/libstagefright/wifi-display/source/TSPacketizer.h b/media/libstagefright/wifi-display/source/TSPacketizer.h
new file mode 100644
index 0000000..9dbeb27
--- /dev/null
+++ b/media/libstagefright/wifi-display/source/TSPacketizer.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2012, 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 TS_PACKETIZER_H_
+
+#define TS_PACKETIZER_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+struct ABuffer;
+struct AMessage;
+
+// Forms the packets of a transport stream given access units.
+// Emits metadata tables (PAT and PMT) and timestamp stream (PCR) based
+// on flags.
+struct TSPacketizer : public RefBase {
+    TSPacketizer();
+
+    // Returns trackIndex or error.
+    ssize_t addTrack(const sp<AMessage> &format);
+
+    enum {
+        EMIT_PAT_AND_PMT = 1,
+        EMIT_PCR         = 2,
+    };
+    status_t packetize(
+            size_t trackIndex, const sp<ABuffer> &accessUnit,
+            sp<ABuffer> *packets,
+            uint32_t flags);
+
+protected:
+    virtual ~TSPacketizer();
+
+private:
+    enum {
+        kPID_PMT = 0x100,
+        kPID_PCR = 0x1000,
+    };
+
+    struct Track;
+
+    Vector<sp<Track> > mTracks;
+
+    unsigned mPATContinuityCounter;
+    unsigned mPMTContinuityCounter;
+
+    uint32_t mCrcTable[256];
+
+    void initCrcTable();
+    uint32_t crc32(const uint8_t *start, size_t size) const;
+
+    DISALLOW_EVIL_CONSTRUCTORS(TSPacketizer);
+};
+
+}  // namespace android
+
+#endif  // TS_PACKETIZER_H_
+
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
new file mode 100644
index 0000000..3f75bc3
--- /dev/null
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
@@ -0,0 +1,944 @@
+/*
+ * Copyright 2012, 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 "WifiDisplaySource"
+#include <utils/Log.h>
+
+#include "WifiDisplaySource.h"
+#include "PlaybackSession.h"
+#include "ParsedMessage.h"
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/MediaErrors.h>
+
+namespace android {
+
+WifiDisplaySource::WifiDisplaySource(const sp<ANetworkSession> &netSession)
+    : mNetSession(netSession),
+      mSessionID(0),
+      mReaperPending(false),
+      mNextCSeq(1) {
+}
+
+WifiDisplaySource::~WifiDisplaySource() {
+}
+
+status_t WifiDisplaySource::start(int32_t port) {
+    sp<AMessage> msg = new AMessage(kWhatStart, id());
+    msg->setInt32("port", port);
+
+    sp<AMessage> response;
+    status_t err = msg->postAndAwaitResponse(&response);
+
+    if (err != OK) {
+        return err;
+    }
+
+    if (!response->findInt32("err", &err)) {
+        err = OK;
+    }
+
+    return err;
+}
+
+status_t WifiDisplaySource::stop() {
+    sp<AMessage> msg = new AMessage(kWhatStop, id());
+
+    sp<AMessage> response;
+    status_t err = msg->postAndAwaitResponse(&response);
+
+    if (err != OK) {
+        return err;
+    }
+
+    if (!response->findInt32("err", &err)) {
+        err = OK;
+    }
+
+    return err;
+}
+
+void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
+    switch (msg->what()) {
+        case kWhatStart:
+        {
+            uint32_t replyID;
+            CHECK(msg->senderAwaitsResponse(&replyID));
+
+            int32_t port;
+            CHECK(msg->findInt32("port", &port));
+
+            sp<AMessage> notify = new AMessage(kWhatRTSPNotify, id());
+
+            status_t err = mNetSession->createRTSPServer(
+                    port, notify, &mSessionID);
+
+            sp<AMessage> response = new AMessage;
+            response->setInt32("err", err);
+            response->postReply(replyID);
+            break;
+        }
+
+        case kWhatRTSPNotify:
+        {
+            int32_t reason;
+            CHECK(msg->findInt32("reason", &reason));
+
+            switch (reason) {
+                case ANetworkSession::kWhatError:
+                {
+                    int32_t sessionID;
+                    CHECK(msg->findInt32("sessionID", &sessionID));
+
+                    int32_t err;
+                    CHECK(msg->findInt32("err", &err));
+
+                    AString detail;
+                    CHECK(msg->findString("detail", &detail));
+
+                    ALOGE("An error occurred in session %d (%d, '%s/%s').",
+                          sessionID,
+                          err,
+                          detail.c_str(),
+                          strerror(-err));
+
+                    mNetSession->destroySession(sessionID);
+
+                    mClientIPs.removeItem(sessionID);
+                    break;
+                }
+
+                case ANetworkSession::kWhatClientConnected:
+                {
+                    int32_t sessionID;
+                    CHECK(msg->findInt32("sessionID", &sessionID));
+
+                    ClientInfo info;
+                    CHECK(msg->findString("client-ip", &info.mRemoteIP));
+                    CHECK(msg->findString("server-ip", &info.mLocalIP));
+                    CHECK(msg->findInt32("server-port", &info.mLocalPort));
+
+                    ALOGI("We now have a client (%d) connected.", sessionID);
+
+                    mClientIPs.add(sessionID, info);
+
+                    status_t err = sendM1(sessionID);
+                    CHECK_EQ(err, (status_t)OK);
+                    break;
+                }
+
+                case ANetworkSession::kWhatData:
+                {
+                    onReceiveClientData(msg);
+                    break;
+                }
+
+                default:
+                    TRESPASS();
+            }
+            break;
+        }
+
+        case kWhatStop:
+        {
+            uint32_t replyID;
+            CHECK(msg->senderAwaitsResponse(&replyID));
+
+            for (size_t i = mPlaybackSessions.size(); i-- > 0;) {
+                const sp<PlaybackSession> &playbackSession =
+                    mPlaybackSessions.valueAt(i);
+
+                looper()->unregisterHandler(playbackSession->id());
+                mPlaybackSessions.removeItemsAt(i);
+            }
+
+            status_t err = OK;
+
+            sp<AMessage> response = new AMessage;
+            response->setInt32("err", err);
+            response->postReply(replyID);
+            break;
+        }
+
+        case kWhatReapDeadClients:
+        {
+            mReaperPending = false;
+
+            for (size_t i = mPlaybackSessions.size(); i-- > 0;) {
+                const sp<PlaybackSession> &playbackSession =
+                    mPlaybackSessions.valueAt(i);
+
+                if (playbackSession->getLastLifesignUs()
+                        + kPlaybackSessionTimeoutUs < ALooper::GetNowUs()) {
+                    ALOGI("playback session %d timed out, reaping.",
+                            mPlaybackSessions.keyAt(i));
+
+                    looper()->unregisterHandler(playbackSession->id());
+                    mPlaybackSessions.removeItemsAt(i);
+                }
+            }
+
+            if (!mPlaybackSessions.isEmpty()) {
+                scheduleReaper();
+            }
+            break;
+        }
+
+        case kWhatPlaybackSessionNotify:
+        {
+            int32_t playbackSessionID;
+            CHECK(msg->findInt32("playbackSessionID", &playbackSessionID));
+
+            int32_t what;
+            CHECK(msg->findInt32("what", &what));
+
+            ssize_t index = mPlaybackSessions.indexOfKey(playbackSessionID);
+            if (index >= 0) {
+                const sp<PlaybackSession> &playbackSession =
+                    mPlaybackSessions.valueAt(index);
+
+                if (what == PlaybackSession::kWhatSessionDead) {
+                    ALOGI("playback sessions %d wants to quit.",
+                          playbackSessionID);
+
+                    looper()->unregisterHandler(playbackSession->id());
+                    mPlaybackSessions.removeItemsAt(index);
+                } else {
+                    CHECK_EQ(what, PlaybackSession::kWhatBinaryData);
+
+                    int32_t channel;
+                    CHECK(msg->findInt32("channel", &channel));
+
+                    sp<ABuffer> data;
+                    CHECK(msg->findBuffer("data", &data));
+
+                    CHECK_LE(channel, 0xffu);
+                    CHECK_LE(data->size(), 0xffffu);
+
+                    int32_t sessionID;
+                    CHECK(msg->findInt32("sessionID", &sessionID));
+
+                    char header[4];
+                    header[0] = '$';
+                    header[1] = channel;
+                    header[2] = data->size() >> 8;
+                    header[3] = data->size() & 0xff;
+
+                    mNetSession->sendRequest(
+                            sessionID, header, sizeof(header));
+
+                    mNetSession->sendRequest(
+                            sessionID, data->data(), data->size());
+                }
+            }
+            break;
+        }
+
+        default:
+            TRESPASS();
+    }
+}
+
+void WifiDisplaySource::registerResponseHandler(
+        int32_t sessionID, int32_t cseq, HandleRTSPResponseFunc func) {
+    ResponseID id;
+    id.mSessionID = sessionID;
+    id.mCSeq = cseq;
+    mResponseHandlers.add(id, func);
+}
+
+status_t WifiDisplaySource::sendM1(int32_t sessionID) {
+    AString request = "OPTIONS * RTSP/1.0\r\n";
+    AppendCommonResponse(&request, mNextCSeq);
+
+    request.append(
+            "Require: org.wfa.wfd1.0\r\n"
+            "\r\n");
+
+    status_t err =
+        mNetSession->sendRequest(sessionID, request.c_str(), request.size());
+
+    if (err != OK) {
+        return err;
+    }
+
+    registerResponseHandler(
+            sessionID, mNextCSeq, &WifiDisplaySource::onReceiveM1Response);
+
+    ++mNextCSeq;
+
+    return OK;
+}
+
+status_t WifiDisplaySource::sendM3(int32_t sessionID) {
+    AString body =
+        "wfd_video_formats\r\n"
+        "wfd_audio_codecs\r\n"
+        "wfd_client_rtp_ports\r\n";
+
+    AString request = "GET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0\r\n";
+    AppendCommonResponse(&request, mNextCSeq);
+
+    request.append("Content-Type: text/parameters\r\n");
+    request.append(StringPrintf("Content-Length: %d\r\n", body.size()));
+    request.append("\r\n");
+    request.append(body);
+
+    status_t err =
+        mNetSession->sendRequest(sessionID, request.c_str(), request.size());
+
+    if (err != OK) {
+        return err;
+    }
+
+    registerResponseHandler(
+            sessionID, mNextCSeq, &WifiDisplaySource::onReceiveM3Response);
+
+    ++mNextCSeq;
+
+    return OK;
+}
+
+status_t WifiDisplaySource::sendM4(int32_t sessionID) {
+    // wfd_video_formats:
+    // 1 byte "native"
+    // 1 byte "preferred-display-mode-supported" 0 or 1
+    // one or more avc codec structures
+    //   1 byte profile
+    //   1 byte level
+    //   4 byte CEA mask
+    //   4 byte VESA mask
+    //   4 byte HH mask
+    //   1 byte latency
+    //   2 byte min-slice-slice
+    //   2 byte slice-enc-params
+    //   1 byte framerate-control-support
+    //   max-hres (none or 2 byte)
+    //   max-vres (none or 2 byte)
+
+    const ClientInfo &info = mClientIPs.valueFor(sessionID);
+
+    AString body = StringPrintf(
+        "wfd_video_formats: "
+        "30 00 02 02 00000040 00000000 00000000 00 0000 0000 00 none none\r\n"
+        "wfd_audio_codecs: AAC 00000001 00\r\n"  // 2 ch AAC 48kHz
+        "wfd_presentation_URL: rtsp://%s:%d/wfd1.0/streamid=0 none\r\n"
+        "wfd_client_rtp_ports: RTP/AVP/UDP;unicast 19000 0 mode=play\r\n",
+        info.mLocalIP.c_str(), info.mLocalPort);
+
+    AString request = "SET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0\r\n";
+    AppendCommonResponse(&request, mNextCSeq);
+
+    request.append("Content-Type: text/parameters\r\n");
+    request.append(StringPrintf("Content-Length: %d\r\n", body.size()));
+    request.append("\r\n");
+    request.append(body);
+
+    status_t err =
+        mNetSession->sendRequest(sessionID, request.c_str(), request.size());
+
+    if (err != OK) {
+        return err;
+    }
+
+    registerResponseHandler(
+            sessionID, mNextCSeq, &WifiDisplaySource::onReceiveM4Response);
+
+    ++mNextCSeq;
+
+    return OK;
+}
+
+status_t WifiDisplaySource::sendM5(int32_t sessionID) {
+    AString body = "wfd_trigger_method: SETUP\r\n";
+
+    AString request = "SET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0\r\n";
+    AppendCommonResponse(&request, mNextCSeq);
+
+    request.append("Content-Type: text/parameters\r\n");
+    request.append(StringPrintf("Content-Length: %d\r\n", body.size()));
+    request.append("\r\n");
+    request.append(body);
+
+    status_t err =
+        mNetSession->sendRequest(sessionID, request.c_str(), request.size());
+
+    if (err != OK) {
+        return err;
+    }
+
+    registerResponseHandler(
+            sessionID, mNextCSeq, &WifiDisplaySource::onReceiveM5Response);
+
+    ++mNextCSeq;
+
+    return OK;
+}
+
+status_t WifiDisplaySource::onReceiveM1Response(
+        int32_t sessionID, const sp<ParsedMessage> &msg) {
+    int32_t statusCode;
+    if (!msg->getStatusCode(&statusCode)) {
+        return ERROR_MALFORMED;
+    }
+
+    if (statusCode != 200) {
+        return ERROR_UNSUPPORTED;
+    }
+
+    return OK;
+}
+
+status_t WifiDisplaySource::onReceiveM3Response(
+        int32_t sessionID, const sp<ParsedMessage> &msg) {
+    int32_t statusCode;
+    if (!msg->getStatusCode(&statusCode)) {
+        return ERROR_MALFORMED;
+    }
+
+    if (statusCode != 200) {
+        return ERROR_UNSUPPORTED;
+    }
+
+    return sendM4(sessionID);
+}
+
+status_t WifiDisplaySource::onReceiveM4Response(
+        int32_t sessionID, const sp<ParsedMessage> &msg) {
+    int32_t statusCode;
+    if (!msg->getStatusCode(&statusCode)) {
+        return ERROR_MALFORMED;
+    }
+
+    if (statusCode != 200) {
+        return ERROR_UNSUPPORTED;
+    }
+
+    return sendM5(sessionID);
+}
+
+status_t WifiDisplaySource::onReceiveM5Response(
+        int32_t sessionID, const sp<ParsedMessage> &msg) {
+    int32_t statusCode;
+    if (!msg->getStatusCode(&statusCode)) {
+        return ERROR_MALFORMED;
+    }
+
+    if (statusCode != 200) {
+        return ERROR_UNSUPPORTED;
+    }
+
+    return OK;
+}
+
+void WifiDisplaySource::scheduleReaper() {
+    if (mReaperPending) {
+        return;
+    }
+
+    mReaperPending = true;
+    (new AMessage(kWhatReapDeadClients, id()))->post(kReaperIntervalUs);
+}
+
+void WifiDisplaySource::onReceiveClientData(const sp<AMessage> &msg) {
+    int32_t sessionID;
+    CHECK(msg->findInt32("sessionID", &sessionID));
+
+    sp<RefBase> obj;
+    CHECK(msg->findObject("data", &obj));
+
+    sp<ParsedMessage> data =
+        static_cast<ParsedMessage *>(obj.get());
+
+    ALOGV("session %d received '%s'",
+          sessionID, data->debugString().c_str());
+
+    AString method;
+    AString uri;
+    data->getRequestField(0, &method);
+
+    int32_t cseq;
+    if (!data->findInt32("cseq", &cseq)) {
+        sendErrorResponse(sessionID, "400 Bad Request", -1 /* cseq */);
+        return;
+    }
+
+    if (method.startsWith("RTSP/")) {
+        // This is a response.
+
+        ResponseID id;
+        id.mSessionID = sessionID;
+        id.mCSeq = cseq;
+
+        ssize_t index = mResponseHandlers.indexOfKey(id);
+
+        if (index < 0) {
+            ALOGW("Received unsolicited server response, cseq %d", cseq);
+            return;
+        }
+
+        HandleRTSPResponseFunc func = mResponseHandlers.valueAt(index);
+        mResponseHandlers.removeItemsAt(index);
+
+        status_t err = (this->*func)(sessionID, data);
+
+        if (err != OK) {
+            ALOGW("Response handler for session %d, cseq %d returned "
+                  "err %d (%s)",
+                  sessionID, cseq, err, strerror(-err));
+        }
+    } else {
+        AString version;
+        data->getRequestField(2, &version);
+        if (!(version == AString("RTSP/1.0"))) {
+            sendErrorResponse(sessionID, "505 RTSP Version not supported", cseq);
+            return;
+        }
+
+        if (method == "DESCRIBE") {
+            onDescribeRequest(sessionID, cseq, data);
+        } else if (method == "OPTIONS") {
+            onOptionsRequest(sessionID, cseq, data);
+        } else if (method == "SETUP") {
+            onSetupRequest(sessionID, cseq, data);
+        } else if (method == "PLAY") {
+            onPlayRequest(sessionID, cseq, data);
+        } else if (method == "PAUSE") {
+            onPauseRequest(sessionID, cseq, data);
+        } else if (method == "TEARDOWN") {
+            onTeardownRequest(sessionID, cseq, data);
+        } else if (method == "GET_PARAMETER") {
+            onGetParameterRequest(sessionID, cseq, data);
+        } else if (method == "SET_PARAMETER") {
+            onSetParameterRequest(sessionID, cseq, data);
+        } else {
+            sendErrorResponse(sessionID, "405 Method Not Allowed", cseq);
+        }
+    }
+}
+
+void WifiDisplaySource::onDescribeRequest(
+        int32_t sessionID,
+        int32_t cseq,
+        const sp<ParsedMessage> &data) {
+    int64_t nowUs = ALooper::GetNowUs();
+
+    AString sdp;
+    sdp.append("v=0\r\n");
+
+    sdp.append(StringPrintf(
+                "o=- %lld %lld IN IP4 0.0.0.0\r\n", nowUs, nowUs));
+
+    sdp.append(
+            "o=- 0 0 IN IP4 127.0.0.0\r\n"
+            "s=Sample\r\n"
+            "c=IN IP4 0.0.0.0\r\n"
+            "b=AS:502\r\n"
+            "t=0 0\r\n"
+            "a=control:*\r\n"
+            "a=range:npt=now-\r\n"
+            "m=video 0 RTP/AVP 33\r\n"
+            "a=rtpmap:33 MP2T/90000\r\n"
+            "a=control:\r\n");
+
+    AString response = "RTSP/1.0 200 OK\r\n";
+    AppendCommonResponse(&response, cseq);
+
+    response.append("Content-Type: application/sdp\r\n");
+
+    // response.append("Content-Base: rtsp://0.0.0.0:7236\r\n");
+    response.append(StringPrintf("Content-Length: %d\r\n", sdp.size()));
+    response.append("\r\n");
+    response.append(sdp);
+
+    status_t err = mNetSession->sendRequest(sessionID, response.c_str());
+    CHECK_EQ(err, (status_t)OK);
+}
+
+void WifiDisplaySource::onOptionsRequest(
+        int32_t sessionID,
+        int32_t cseq,
+        const sp<ParsedMessage> &data) {
+    int32_t playbackSessionID;
+    sp<PlaybackSession> playbackSession =
+        findPlaybackSession(data, &playbackSessionID);
+
+    if (playbackSession != NULL) {
+        playbackSession->updateLiveness();
+    }
+
+    AString response = "RTSP/1.0 200 OK\r\n";
+    AppendCommonResponse(&response, cseq);
+
+    response.append(
+            "Public: org.wfa.wfd1.0, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, "
+            "GET_PARAMETER, SET_PARAMETER\r\n");
+
+    response.append("\r\n");
+
+    status_t err = mNetSession->sendRequest(sessionID, response.c_str());
+    CHECK_EQ(err, (status_t)OK);
+
+    err = sendM3(sessionID);
+    CHECK_EQ(err, (status_t)OK);
+}
+
+void WifiDisplaySource::onSetupRequest(
+        int32_t sessionID,
+        int32_t cseq,
+        const sp<ParsedMessage> &data) {
+    AString transport;
+    if (!data->findString("transport", &transport)) {
+        sendErrorResponse(sessionID, "400 Bad Request", cseq);
+        return;
+    }
+
+    bool useInterleavedTCP = false;
+
+    int clientRtp, clientRtcp;
+    if (transport.startsWith("RTP/AVP/TCP;")) {
+        AString interleaved;
+        if (!ParsedMessage::GetAttribute(
+                    transport.c_str(), "interleaved", &interleaved)
+                || sscanf(interleaved.c_str(), "%d-%d",
+                          &clientRtp, &clientRtcp) != 2) {
+            sendErrorResponse(sessionID, "400 Bad Request", cseq);
+            return;
+        }
+
+        useInterleavedTCP = true;
+    } else if (transport.startsWith("RTP/AVP;unicast;")
+            || transport.startsWith("RTP/AVP/UDP;unicast;")) {
+        bool badRequest = false;
+
+        AString clientPort;
+        if (!ParsedMessage::GetAttribute(
+                    transport.c_str(), "client_port", &clientPort)) {
+            badRequest = true;
+        } else if (sscanf(clientPort.c_str(), "%d-%d",
+                          &clientRtp, &clientRtcp) == 2) {
+        } else if (sscanf(clientPort.c_str(), "%d", &clientRtp) == 1) {
+            // No RTCP.
+            clientRtcp = -1;
+        } else {
+            badRequest = true;
+        }
+
+        if (badRequest) {
+            sendErrorResponse(sessionID, "400 Bad Request", cseq);
+            return;
+        }
+#if 1
+    // The LG dongle doesn't specify client_port=xxx apparently.
+    } else if (transport == "RTP/AVP/UDP;unicast") {
+        clientRtp = 19000;
+        clientRtcp = clientRtp + 1;
+#endif
+    } else {
+        sendErrorResponse(sessionID, "461 Unsupported Transport", cseq);
+        return;
+    }
+
+    int32_t playbackSessionID = makeUniquePlaybackSessionID();
+
+    sp<AMessage> notify = new AMessage(kWhatPlaybackSessionNotify, id());
+    notify->setInt32("playbackSessionID", playbackSessionID);
+    notify->setInt32("sessionID", sessionID);
+
+    sp<PlaybackSession> playbackSession =
+        new PlaybackSession(mNetSession, notify);
+
+    looper()->registerHandler(playbackSession);
+
+    AString uri;
+    data->getRequestField(1, &uri);
+
+    if (strncasecmp("rtsp://", uri.c_str(), 7)) {
+        sendErrorResponse(sessionID, "400 Bad Request", cseq);
+        return;
+    }
+
+    if (!(uri.startsWith("rtsp://") && uri.endsWith("/wfd1.0/streamid=0"))) {
+        sendErrorResponse(sessionID, "404 Not found", cseq);
+        return;
+    }
+
+    const ClientInfo &info = mClientIPs.valueFor(sessionID);
+
+    status_t err = playbackSession->init(
+            info.mRemoteIP.c_str(),
+            clientRtp,
+            clientRtcp,
+            useInterleavedTCP);
+
+    if (err != OK) {
+        looper()->unregisterHandler(playbackSession->id());
+        playbackSession.clear();
+    }
+
+    switch (err) {
+        case OK:
+            break;
+        case -ENOENT:
+            sendErrorResponse(sessionID, "404 Not Found", cseq);
+            return;
+        default:
+            sendErrorResponse(sessionID, "403 Forbidden", cseq);
+            return;
+    }
+
+    mPlaybackSessions.add(playbackSessionID, playbackSession);
+
+    AString response = "RTSP/1.0 200 OK\r\n";
+    AppendCommonResponse(&response, cseq, playbackSessionID);
+
+    if (useInterleavedTCP) {
+        response.append(
+                StringPrintf(
+                    "Transport: RTP/AVP/TCP;interleaved=%d-%d;",
+                    clientRtp, clientRtcp));
+    } else {
+        int32_t serverRtp = playbackSession->getRTPPort();
+
+        if (clientRtcp >= 0) {
+            response.append(
+                    StringPrintf(
+                        "Transport: RTP/AVP;unicast;client_port=%d-%d;"
+                        "server_port=%d-%d\r\n",
+                        clientRtp, clientRtcp, serverRtp, serverRtp + 1));
+        } else {
+            response.append(
+                    StringPrintf(
+                        "Transport: RTP/AVP;unicast;client_port=%d;"
+                        "server_port=%d\r\n",
+                        clientRtp, serverRtp));
+        }
+    }
+
+    response.append("\r\n");
+
+    err = mNetSession->sendRequest(sessionID, response.c_str());
+    CHECK_EQ(err, (status_t)OK);
+
+#if 0
+    // XXX the dongle does not currently send keep-alives.
+    scheduleReaper();
+#endif
+}
+
+void WifiDisplaySource::onPlayRequest(
+        int32_t sessionID,
+        int32_t cseq,
+        const sp<ParsedMessage> &data) {
+    int32_t playbackSessionID;
+    sp<PlaybackSession> playbackSession =
+        findPlaybackSession(data, &playbackSessionID);
+
+    if (playbackSession == NULL) {
+        sendErrorResponse(sessionID, "454 Session Not Found", cseq);
+        return;
+    }
+
+    status_t err = playbackSession->play();
+    CHECK_EQ(err, (status_t)OK);
+
+    AString response = "RTSP/1.0 200 OK\r\n";
+    AppendCommonResponse(&response, cseq, playbackSessionID);
+    response.append("Range: npt=now-\r\n");
+    response.append("\r\n");
+
+    err = mNetSession->sendRequest(sessionID, response.c_str());
+    CHECK_EQ(err, (status_t)OK);
+}
+
+void WifiDisplaySource::onPauseRequest(
+        int32_t sessionID,
+        int32_t cseq,
+        const sp<ParsedMessage> &data) {
+    int32_t playbackSessionID;
+    sp<PlaybackSession> playbackSession =
+        findPlaybackSession(data, &playbackSessionID);
+
+    if (playbackSession == NULL) {
+        sendErrorResponse(sessionID, "454 Session Not Found", cseq);
+        return;
+    }
+
+    status_t err = playbackSession->pause();
+    CHECK_EQ(err, (status_t)OK);
+
+    AString response = "RTSP/1.0 200 OK\r\n";
+    AppendCommonResponse(&response, cseq, playbackSessionID);
+    response.append("\r\n");
+
+    err = mNetSession->sendRequest(sessionID, response.c_str());
+    CHECK_EQ(err, (status_t)OK);
+}
+
+void WifiDisplaySource::onTeardownRequest(
+        int32_t sessionID,
+        int32_t cseq,
+        const sp<ParsedMessage> &data) {
+    int32_t playbackSessionID;
+    sp<PlaybackSession> playbackSession =
+        findPlaybackSession(data, &playbackSessionID);
+
+    if (playbackSession == NULL) {
+        sendErrorResponse(sessionID, "454 Session Not Found", cseq);
+        return;
+    }
+
+    looper()->unregisterHandler(playbackSession->id());
+    mPlaybackSessions.removeItem(playbackSessionID);
+
+    AString response = "RTSP/1.0 200 OK\r\n";
+    AppendCommonResponse(&response, cseq, playbackSessionID);
+    response.append("\r\n");
+
+    status_t err = mNetSession->sendRequest(sessionID, response.c_str());
+    CHECK_EQ(err, (status_t)OK);
+}
+
+void WifiDisplaySource::onGetParameterRequest(
+        int32_t sessionID,
+        int32_t cseq,
+        const sp<ParsedMessage> &data) {
+    int32_t playbackSessionID;
+    sp<PlaybackSession> playbackSession =
+        findPlaybackSession(data, &playbackSessionID);
+
+    if (playbackSession == NULL) {
+        sendErrorResponse(sessionID, "454 Session Not Found", cseq);
+        return;
+    }
+
+    playbackSession->updateLiveness();
+
+    AString response = "RTSP/1.0 200 OK\r\n";
+    AppendCommonResponse(&response, cseq, playbackSessionID);
+    response.append("\r\n");
+
+    status_t err = mNetSession->sendRequest(sessionID, response.c_str());
+    CHECK_EQ(err, (status_t)OK);
+}
+
+void WifiDisplaySource::onSetParameterRequest(
+        int32_t sessionID,
+        int32_t cseq,
+        const sp<ParsedMessage> &data) {
+    int32_t playbackSessionID;
+#if 0
+    // XXX the dongle does not include a "Session:" header in this request.
+    sp<PlaybackSession> playbackSession =
+        findPlaybackSession(data, &playbackSessionID);
+
+    if (playbackSession == NULL) {
+        sendErrorResponse(sessionID, "454 Session Not Found", cseq);
+        return;
+    }
+#else
+    CHECK_EQ(mPlaybackSessions.size(), 1u);
+    playbackSessionID = mPlaybackSessions.keyAt(0);
+    sp<PlaybackSession> playbackSession = mPlaybackSessions.valueAt(0);
+#endif
+
+    playbackSession->updateLiveness();
+
+    AString response = "RTSP/1.0 200 OK\r\n";
+    AppendCommonResponse(&response, cseq, playbackSessionID);
+    response.append("\r\n");
+
+    status_t err = mNetSession->sendRequest(sessionID, response.c_str());
+    CHECK_EQ(err, (status_t)OK);
+}
+
+// static
+void WifiDisplaySource::AppendCommonResponse(
+        AString *response, int32_t cseq, int32_t playbackSessionID) {
+    time_t now = time(NULL);
+    struct tm *now2 = gmtime(&now);
+    char buf[128];
+    strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S %z", now2);
+
+    response->append("Date: ");
+    response->append(buf);
+    response->append("\r\n");
+
+    response->append("Server: Mine/1.0\r\n");
+
+    if (cseq >= 0) {
+        response->append(StringPrintf("CSeq: %d\r\n", cseq));
+    }
+
+    if (playbackSessionID >= 0ll) {
+        response->append(
+                StringPrintf(
+                    "Session: %d;timeout=%lld\r\n",
+                    playbackSessionID, kPlaybackSessionTimeoutSecs));
+    }
+}
+
+void WifiDisplaySource::sendErrorResponse(
+        int32_t sessionID,
+        const char *errorDetail,
+        int32_t cseq) {
+    AString response;
+    response.append("RTSP/1.0 ");
+    response.append(errorDetail);
+    response.append("\r\n");
+
+    AppendCommonResponse(&response, cseq);
+
+    response.append("\r\n");
+
+    status_t err = mNetSession->sendRequest(sessionID, response.c_str());
+    CHECK_EQ(err, (status_t)OK);
+}
+
+int32_t WifiDisplaySource::makeUniquePlaybackSessionID() const {
+    for (;;) {
+        int32_t playbackSessionID = rand();
+
+        for (size_t i = 0; i < mPlaybackSessions.size(); ++i) {
+            if (mPlaybackSessions.keyAt(i) == playbackSessionID) {
+                continue;
+            }
+        }
+
+        return playbackSessionID;
+    }
+}
+
+sp<WifiDisplaySource::PlaybackSession> WifiDisplaySource::findPlaybackSession(
+        const sp<ParsedMessage> &data, int32_t *playbackSessionID) const {
+    if (!data->findInt32("session", playbackSessionID)) {
+        *playbackSessionID = 0;
+        return NULL;
+    }
+
+    ssize_t index = mPlaybackSessions.indexOfKey(*playbackSessionID);
+    if (index < 0) {
+        return NULL;
+    }
+
+    return mPlaybackSessions.valueAt(index);
+}
+
+}  // namespace android
+
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.h b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
new file mode 100644
index 0000000..95c3560
--- /dev/null
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2012, 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 WIFI_DISPLAY_SOURCE_H_
+
+#define WIFI_DISPLAY_SOURCE_H_
+
+#include "ANetworkSession.h"
+
+#include <media/stagefright/foundation/AHandler.h>
+
+namespace android {
+
+struct ParsedMessage;
+
+// Represents the RTSP server acting as a wifi display source.
+// Manages incoming connections, sets up Playback sessions as necessary.
+struct WifiDisplaySource : public AHandler {
+    static const unsigned kWifiDisplayDefaultPort = 7236;
+
+    WifiDisplaySource(const sp<ANetworkSession> &netSession);
+
+    status_t start(int32_t port);
+    status_t stop();
+
+protected:
+    virtual ~WifiDisplaySource();
+    virtual void onMessageReceived(const sp<AMessage> &msg);
+
+private:
+    struct PlaybackSession;
+
+    enum {
+        kWhatStart,
+        kWhatRTSPNotify,
+        kWhatStop,
+        kWhatReapDeadClients,
+        kWhatPlaybackSessionNotify,
+    };
+
+    struct ResponseID {
+        int32_t mSessionID;
+        int32_t mCSeq;
+
+        bool operator<(const ResponseID &other) const {
+            return mSessionID < other.mSessionID
+                || (mSessionID == other.mSessionID
+                        && mCSeq < other.mCSeq);
+        }
+    };
+
+    typedef status_t (WifiDisplaySource::*HandleRTSPResponseFunc)(
+            int32_t sessionID, const sp<ParsedMessage> &msg);
+
+    static const int64_t kReaperIntervalUs = 1000000ll;
+
+    static const int64_t kPlaybackSessionTimeoutSecs = 30;
+
+    static const int64_t kPlaybackSessionTimeoutUs =
+        kPlaybackSessionTimeoutSecs * 1000000ll;
+
+    sp<ANetworkSession> mNetSession;
+    int32_t mSessionID;
+
+    struct ClientInfo {
+        AString mRemoteIP;
+        AString mLocalIP;
+        int32_t mLocalPort;
+    };
+    KeyedVector<int32_t, ClientInfo> mClientIPs;
+
+    bool mReaperPending;
+
+    int32_t mNextCSeq;
+
+    KeyedVector<ResponseID, HandleRTSPResponseFunc> mResponseHandlers;
+
+    KeyedVector<int32_t, sp<PlaybackSession> > mPlaybackSessions;
+
+    status_t sendM1(int32_t sessionID);
+    status_t sendM3(int32_t sessionID);
+    status_t sendM4(int32_t sessionID);
+    status_t sendM5(int32_t sessionID);
+
+    status_t onReceiveM1Response(
+            int32_t sessionID, const sp<ParsedMessage> &msg);
+
+    status_t onReceiveM3Response(
+            int32_t sessionID, const sp<ParsedMessage> &msg);
+
+    status_t onReceiveM4Response(
+            int32_t sessionID, const sp<ParsedMessage> &msg);
+
+    status_t onReceiveM5Response(
+            int32_t sessionID, const sp<ParsedMessage> &msg);
+
+    void registerResponseHandler(
+            int32_t sessionID, int32_t cseq, HandleRTSPResponseFunc func);
+
+    void onReceiveClientData(const sp<AMessage> &msg);
+
+    void onDescribeRequest(
+            int32_t sessionID,
+            int32_t cseq,
+            const sp<ParsedMessage> &data);
+
+    void onOptionsRequest(
+            int32_t sessionID,
+            int32_t cseq,
+            const sp<ParsedMessage> &data);
+
+    void onSetupRequest(
+            int32_t sessionID,
+            int32_t cseq,
+            const sp<ParsedMessage> &data);
+
+    void onPlayRequest(
+            int32_t sessionID,
+            int32_t cseq,
+            const sp<ParsedMessage> &data);
+
+    void onPauseRequest(
+            int32_t sessionID,
+            int32_t cseq,
+            const sp<ParsedMessage> &data);
+
+    void onTeardownRequest(
+            int32_t sessionID,
+            int32_t cseq,
+            const sp<ParsedMessage> &data);
+
+    void onGetParameterRequest(
+            int32_t sessionID,
+            int32_t cseq,
+            const sp<ParsedMessage> &data);
+
+    void onSetParameterRequest(
+            int32_t sessionID,
+            int32_t cseq,
+            const sp<ParsedMessage> &data);
+
+    void sendErrorResponse(
+            int32_t sessionID,
+            const char *errorDetail,
+            int32_t cseq);
+
+    static void AppendCommonResponse(
+            AString *response, int32_t cseq, int32_t playbackSessionID = -1ll);
+
+    void scheduleReaper();
+
+    int32_t makeUniquePlaybackSessionID() const;
+
+    sp<PlaybackSession> findPlaybackSession(
+            const sp<ParsedMessage> &data, int32_t *playbackSessionID) const;
+
+    DISALLOW_EVIL_CONSTRUCTORS(WifiDisplaySource);
+};
+
+}  // namespace android
+
+#endif  // WIFI_DISPLAY_SOURCE_H_
diff --git a/media/libstagefright/wifi-display/wfd.cpp b/media/libstagefright/wifi-display/wfd.cpp
new file mode 100644
index 0000000..32cdf3f
--- /dev/null
+++ b/media/libstagefright/wifi-display/wfd.cpp
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2012, 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 "wfd"
+#include <utils/Log.h>
+
+#define SUPPORT_SINK    0
+
+#if SUPPORT_SINK
+#include "sink/WifiDisplaySink.h"
+#endif
+
+#include <binder/ProcessState.h>
+#include <binder/IServiceManager.h>
+#include <media/IMediaPlayerService.h>
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/foundation/ADebug.h>
+
+namespace android {
+
+static void enableDisableRemoteDisplay(bool enable) {
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> binder = sm->getService(String16("media.player"));
+
+    sp<IMediaPlayerService> service =
+        interface_cast<IMediaPlayerService>(binder);
+
+    CHECK(service.get() != NULL);
+
+    service->enableRemoteDisplay(enable);
+}
+
+}  // namespace android
+
+static void usage(const char *me) {
+    fprintf(stderr,
+            "usage:\n"
+#if SUPPORT_SINK
+            "           %s -c host[:port]\tconnect to wifi source\n"
+            "           -u uri        \tconnect to an rtsp uri\n"
+#endif
+            "           -e            \tenable remote display\n"
+            "           -d            \tdisable remote display\n",
+            me);
+}
+
+int main(int argc, char **argv) {
+    using namespace android;
+
+    ProcessState::self()->startThreadPool();
+
+    DataSource::RegisterDefaultSniffers();
+
+    AString connectToHost;
+    int32_t connectToPort = -1;
+    AString uri;
+
+    int res;
+    while ((res = getopt(argc, argv, "hc:l:u:ed")) >= 0) {
+        switch (res) {
+#if SUPPORT_SINK
+            case 'c':
+            {
+                const char *colonPos = strrchr(optarg, ':');
+
+                if (colonPos == NULL) {
+                    connectToHost = optarg;
+                    connectToPort = WifiDisplaySource::kWifiDisplayDefaultPort;
+                } else {
+                    connectToHost.setTo(optarg, colonPos - optarg);
+
+                    char *end;
+                    connectToPort = strtol(colonPos + 1, &end, 10);
+
+                    if (*end != '\0' || end == colonPos + 1
+                            || connectToPort < 1 || connectToPort > 65535) {
+                        fprintf(stderr, "Illegal port specified.\n");
+                        exit(1);
+                    }
+                }
+                break;
+            }
+
+            case 'u':
+            {
+                uri = optarg;
+                break;
+            }
+#endif
+
+            case 'e':
+            case 'd':
+            {
+                enableDisableRemoteDisplay(res == 'e');
+                exit(0);
+                break;
+            }
+
+            case '?':
+            case 'h':
+            default:
+                usage(argv[0]);
+                exit(1);
+        }
+    }
+
+#if SUPPORT_SINK
+    if (connectToPort < 0 && uri.empty()) {
+        fprintf(stderr,
+                "You need to select either source host or uri.\n");
+
+        exit(1);
+    }
+
+    if (connectToPort >= 0 && !uri.empty()) {
+        fprintf(stderr,
+                "You need to either connect to a wfd host or an rtsp url, "
+                "not both.\n");
+        exit(1);
+    }
+
+    sp<ANetworkSession> session = new ANetworkSession;
+    session->start();
+
+    sp<ALooper> looper = new ALooper;
+
+    sp<WifiDisplaySink> sink = new WifiDisplaySink(session);
+    looper->registerHandler(sink);
+
+    if (connectToPort >= 0) {
+        sink->start(connectToHost.c_str(), connectToPort);
+    } else {
+        sink->start(uri.c_str());
+    }
+
+    looper->start(true /* runOnCallingThread */);
+#endif
+
+    return 0;
+}
