diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index db9093a..9c8451c 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -83,6 +83,10 @@
     virtual status_t storeMetaDataInBuffers(
             node_id node, OMX_U32 port_index, OMX_BOOL enable) = 0;
 
+    virtual status_t prepareForAdaptivePlayback(
+            node_id node, OMX_U32 portIndex, OMX_BOOL enable,
+            OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) = 0;
+
     virtual status_t enableGraphicBuffers(
             node_id node, OMX_U32 port_index, OMX_BOOL enable) = 0;
 
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index ef99f4f..71ce320 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -43,6 +43,7 @@
     CREATE_INPUT_SURFACE,
     SIGNAL_END_OF_INPUT_STREAM,
     STORE_META_DATA_IN_BUFFERS,
+    PREPARE_FOR_ADAPTIVE_PLAYBACK,
     ALLOC_BUFFER,
     ALLOC_BUFFER_WITH_BACKUP,
     FREE_BUFFER,
@@ -351,6 +352,22 @@
         return err;
     }
 
+    virtual status_t prepareForAdaptivePlayback(
+            node_id node, OMX_U32 port_index, OMX_BOOL enable,
+            OMX_U32 max_width, OMX_U32 max_height) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
+        data.writeIntPtr((intptr_t)node);
+        data.writeInt32(port_index);
+        data.writeInt32((int32_t)enable);
+        data.writeInt32(max_width);
+        data.writeInt32(max_height);
+        remote()->transact(PREPARE_FOR_ADAPTIVE_PLAYBACK, data, &reply);
+
+        status_t err = reply.readInt32();
+        return err;
+    }
+
     virtual status_t allocateBuffer(
             node_id node, OMX_U32 port_index, size_t size,
             buffer_id *buffer, void **buffer_data) {
@@ -770,6 +787,23 @@
             return NO_ERROR;
         }
 
+        case PREPARE_FOR_ADAPTIVE_PLAYBACK:
+        {
+            CHECK_OMX_INTERFACE(IOMX, data, reply);
+
+            node_id node = (void*)data.readIntPtr();
+            OMX_U32 port_index = data.readInt32();
+            OMX_BOOL enable = (OMX_BOOL)data.readInt32();
+            OMX_U32 max_width = data.readInt32();
+            OMX_U32 max_height = data.readInt32();
+
+            status_t err = prepareForAdaptivePlayback(
+                    node, port_index, enable, max_width, max_height);
+            reply->writeInt32(err);
+
+            return NO_ERROR;
+        }
+
         case ALLOC_BUFFER:
         {
             CHECK_OMX_INTERFACE(IOMX, data, reply);
diff --git a/media/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp
index 9820ef5..9f9352d 100644
--- a/media/libstagefright/OMXClient.cpp
+++ b/media/libstagefright/OMXClient.cpp
@@ -69,6 +69,10 @@
     virtual status_t storeMetaDataInBuffers(
             node_id node, OMX_U32 port_index, OMX_BOOL enable);
 
+    virtual status_t prepareForAdaptivePlayback(
+            node_id node, OMX_U32 port_index, OMX_BOOL enable,
+            OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight);
+
     virtual status_t enableGraphicBuffers(
             node_id node, OMX_U32 port_index, OMX_BOOL enable);
 
@@ -268,6 +272,13 @@
     return getOMX(node)->storeMetaDataInBuffers(node, port_index, enable);
 }
 
+status_t MuxOMX::prepareForAdaptivePlayback(
+        node_id node, OMX_U32 port_index, OMX_BOOL enable,
+        OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) {
+    return getOMX(node)->prepareForAdaptivePlayback(
+            node, port_index, enable, maxFrameWidth, maxFrameHeight);
+}
+
 status_t MuxOMX::enableGraphicBuffers(
         node_id node, OMX_U32 port_index, OMX_BOOL enable) {
     return getOMX(node)->enableGraphicBuffers(node, port_index, enable);
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index 7e53af3..31a5077 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -71,6 +71,10 @@
     virtual status_t storeMetaDataInBuffers(
             node_id node, OMX_U32 port_index, OMX_BOOL enable);
 
+    virtual status_t prepareForAdaptivePlayback(
+            node_id node, OMX_U32 portIndex, OMX_BOOL enable,
+            OMX_U32 max_frame_width, OMX_U32 max_frame_height);
+
     virtual status_t useBuffer(
             node_id node, OMX_U32 port_index, const sp<IMemory> &params,
             buffer_id *buffer);
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index ae498b4..339179e 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -58,6 +58,10 @@
 
     status_t storeMetaDataInBuffers(OMX_U32 portIndex, OMX_BOOL enable);
 
+    status_t prepareForAdaptivePlayback(
+            OMX_U32 portIndex, OMX_BOOL enable,
+            OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight);
+
     status_t useBuffer(
             OMX_U32 portIndex, const sp<IMemory> &params,
             OMX::buffer_id *buffer);
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index aaa9f89..84a0e10 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -331,6 +331,13 @@
     return findInstance(node)->storeMetaDataInBuffers(port_index, enable);
 }
 
+status_t OMX::prepareForAdaptivePlayback(
+        node_id node, OMX_U32 portIndex, OMX_BOOL enable,
+        OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) {
+    return findInstance(node)->prepareForAdaptivePlayback(
+            portIndex, enable, maxFrameWidth, maxFrameHeight);
+}
+
 status_t OMX::useBuffer(
         node_id node, OMX_U32 port_index, const sp<IMemory> &params,
         buffer_id *buffer) {
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index ef683a0..46e5d71 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -417,6 +417,40 @@
     return err;
 }
 
+status_t OMXNodeInstance::prepareForAdaptivePlayback(
+        OMX_U32 portIndex, OMX_BOOL enable, OMX_U32 maxFrameWidth,
+        OMX_U32 maxFrameHeight) {
+    Mutex::Autolock autolock(mLock);
+
+    OMX_INDEXTYPE index;
+    OMX_STRING name = const_cast<OMX_STRING>(
+            "OMX.google.android.index.prepareForAdaptivePlayback");
+
+    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
+    if (err != OMX_ErrorNone) {
+        ALOGW_IF(enable, "OMX_GetExtensionIndex %s failed", name);
+        return StatusFromOMXError(err);
+    }
+
+    PrepareForAdaptivePlaybackParams params;
+    params.nSize = sizeof(params);
+    params.nVersion.s.nVersionMajor = 1;
+    params.nVersion.s.nVersionMinor = 0;
+    params.nVersion.s.nRevision = 0;
+    params.nVersion.s.nStep = 0;
+
+    params.nPortIndex = portIndex;
+    params.bEnable = enable;
+    params.nMaxFrameWidth = maxFrameWidth;
+    params.nMaxFrameHeight = maxFrameHeight;
+    if ((err = OMX_SetParameter(mHandle, index, &params)) != OMX_ErrorNone) {
+        ALOGW("OMX_SetParameter failed for PrepareForAdaptivePlayback "
+              "with error %d (0x%08x)", err, err);
+        return UNKNOWN_ERROR;
+    }
+    return err;
+}
+
 status_t OMXNodeInstance::useBuffer(
         OMX_U32 portIndex, const sp<IMemory> &params,
         OMX::buffer_id *buffer) {
diff --git a/media/libstagefright/wifi-display/Android.mk b/media/libstagefright/wifi-display/Android.mk
index c7d107e..f70454a 100644
--- a/media/libstagefright/wifi-display/Android.mk
+++ b/media/libstagefright/wifi-display/Android.mk
@@ -3,16 +3,9 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-        MediaReceiver.cpp               \
         MediaSender.cpp                 \
         Parameters.cpp                  \
-        rtp/RTPAssembler.cpp            \
-        rtp/RTPReceiver.cpp             \
         rtp/RTPSender.cpp               \
-        sink/DirectRenderer.cpp         \
-        sink/WifiDisplaySink.cpp        \
-        SNTPClient.cpp                  \
-        TimeSyncer.cpp                  \
         source/Converter.cpp            \
         source/MediaPuller.cpp          \
         source/PlaybackSession.cpp      \
@@ -42,87 +35,3 @@
 LOCAL_MODULE_TAGS:= optional
 
 include $(BUILD_SHARED_LIBRARY)
-
-################################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-        wfd.cpp                 \
-
-LOCAL_SHARED_LIBRARIES:= \
-        libbinder                       \
-        libgui                          \
-        libmedia                        \
-        libstagefright                  \
-        libstagefright_foundation       \
-        libstagefright_wfd              \
-        libutils                        \
-        liblog                          \
-
-LOCAL_MODULE:= wfd
-
-include $(BUILD_EXECUTABLE)
-
-################################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-        udptest.cpp                 \
-
-LOCAL_SHARED_LIBRARIES:= \
-        libbinder                       \
-        libgui                          \
-        libmedia                        \
-        libstagefright                  \
-        libstagefright_foundation       \
-        libstagefright_wfd              \
-        libutils                        \
-        liblog                          \
-
-LOCAL_MODULE:= udptest
-
-include $(BUILD_EXECUTABLE)
-
-################################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-        rtptest.cpp                 \
-
-LOCAL_SHARED_LIBRARIES:= \
-        libbinder                       \
-        libgui                          \
-        libmedia                        \
-        libstagefright                  \
-        libstagefright_foundation       \
-        libstagefright_wfd              \
-        libutils                        \
-        liblog                          \
-
-LOCAL_MODULE:= rtptest
-
-include $(BUILD_EXECUTABLE)
-
-################################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-        nettest.cpp                     \
-
-LOCAL_SHARED_LIBRARIES:= \
-        libbinder                       \
-        libgui                          \
-        libmedia                        \
-        libstagefright                  \
-        libstagefright_foundation       \
-        libstagefright_wfd              \
-        libutils                        \
-        liblog                          \
-
-LOCAL_MODULE:= nettest
-
-include $(BUILD_EXECUTABLE)
diff --git a/media/libstagefright/wifi-display/MediaReceiver.cpp b/media/libstagefright/wifi-display/MediaReceiver.cpp
deleted file mode 100644
index 5524235..0000000
--- a/media/libstagefright/wifi-display/MediaReceiver.cpp
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Copyright 2013, 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 "MediaReceiver"
-#include <utils/Log.h>
-
-#include "MediaReceiver.h"
-
-#include "AnotherPacketSource.h"
-#include "rtp/RTPReceiver.h"
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/ANetworkSession.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/Utils.h>
-
-namespace android {
-
-MediaReceiver::MediaReceiver(
-        const sp<ANetworkSession> &netSession,
-        const sp<AMessage> &notify)
-    : mNetSession(netSession),
-      mNotify(notify),
-      mMode(MODE_UNDEFINED),
-      mGeneration(0),
-      mInitStatus(OK),
-      mInitDoneCount(0) {
-}
-
-MediaReceiver::~MediaReceiver() {
-}
-
-ssize_t MediaReceiver::addTrack(
-        RTPReceiver::TransportMode rtpMode,
-        RTPReceiver::TransportMode rtcpMode,
-        int32_t *localRTPPort) {
-    if (mMode != MODE_UNDEFINED) {
-        return INVALID_OPERATION;
-    }
-
-    size_t trackIndex = mTrackInfos.size();
-
-    TrackInfo info;
-
-    sp<AMessage> notify = new AMessage(kWhatReceiverNotify, id());
-    notify->setInt32("generation", mGeneration);
-    notify->setSize("trackIndex", trackIndex);
-
-    info.mReceiver = new RTPReceiver(mNetSession, notify);
-    looper()->registerHandler(info.mReceiver);
-
-    info.mReceiver->registerPacketType(
-            33, RTPReceiver::PACKETIZATION_TRANSPORT_STREAM);
-
-    info.mReceiver->registerPacketType(
-            96, RTPReceiver::PACKETIZATION_AAC);
-
-    info.mReceiver->registerPacketType(
-            97, RTPReceiver::PACKETIZATION_H264);
-
-    status_t err = info.mReceiver->initAsync(
-            rtpMode,
-            rtcpMode,
-            localRTPPort);
-
-    if (err != OK) {
-        looper()->unregisterHandler(info.mReceiver->id());
-        info.mReceiver.clear();
-
-        return err;
-    }
-
-    mTrackInfos.push_back(info);
-
-    return trackIndex;
-}
-
-status_t MediaReceiver::connectTrack(
-        size_t trackIndex,
-        const char *remoteHost,
-        int32_t remoteRTPPort,
-        int32_t remoteRTCPPort) {
-    if (trackIndex >= mTrackInfos.size()) {
-        return -ERANGE;
-    }
-
-    TrackInfo *info = &mTrackInfos.editItemAt(trackIndex);
-    return info->mReceiver->connect(remoteHost, remoteRTPPort, remoteRTCPPort);
-}
-
-status_t MediaReceiver::initAsync(Mode mode) {
-    if ((mode == MODE_TRANSPORT_STREAM || mode == MODE_TRANSPORT_STREAM_RAW)
-            && mTrackInfos.size() > 1) {
-        return INVALID_OPERATION;
-    }
-
-    sp<AMessage> msg = new AMessage(kWhatInit, id());
-    msg->setInt32("mode", mode);
-    msg->post();
-
-    return OK;
-}
-
-void MediaReceiver::onMessageReceived(const sp<AMessage> &msg) {
-    switch (msg->what()) {
-        case kWhatInit:
-        {
-            int32_t mode;
-            CHECK(msg->findInt32("mode", &mode));
-
-            CHECK_EQ(mMode, MODE_UNDEFINED);
-            mMode = (Mode)mode;
-
-            if (mInitStatus != OK || mInitDoneCount == mTrackInfos.size()) {
-                notifyInitDone(mInitStatus);
-            }
-
-            mTSParser = new ATSParser(
-                    ATSParser::ALIGNED_VIDEO_DATA
-                        | ATSParser::TS_TIMESTAMPS_ARE_ABSOLUTE);
-
-            mFormatKnownMask = 0;
-            break;
-        }
-
-        case kWhatReceiverNotify:
-        {
-            int32_t generation;
-            CHECK(msg->findInt32("generation", &generation));
-            if (generation != mGeneration) {
-                break;
-            }
-
-            onReceiverNotify(msg);
-            break;
-        }
-
-        default:
-            TRESPASS();
-    }
-}
-
-void MediaReceiver::onReceiverNotify(const sp<AMessage> &msg) {
-    int32_t what;
-    CHECK(msg->findInt32("what", &what));
-
-    switch (what) {
-        case RTPReceiver::kWhatInitDone:
-        {
-            ++mInitDoneCount;
-
-            int32_t err;
-            CHECK(msg->findInt32("err", &err));
-
-            if (err != OK) {
-                mInitStatus = err;
-                ++mGeneration;
-            }
-
-            if (mMode != MODE_UNDEFINED) {
-                if (mInitStatus != OK || mInitDoneCount == mTrackInfos.size()) {
-                    notifyInitDone(mInitStatus);
-                }
-            }
-            break;
-        }
-
-        case RTPReceiver::kWhatError:
-        {
-            int32_t err;
-            CHECK(msg->findInt32("err", &err));
-
-            notifyError(err);
-            break;
-        }
-
-        case RTPReceiver::kWhatAccessUnit:
-        {
-            size_t trackIndex;
-            CHECK(msg->findSize("trackIndex", &trackIndex));
-
-            sp<ABuffer> accessUnit;
-            CHECK(msg->findBuffer("accessUnit", &accessUnit));
-
-            int32_t followsDiscontinuity;
-            if (!msg->findInt32(
-                        "followsDiscontinuity", &followsDiscontinuity)) {
-                followsDiscontinuity = 0;
-            }
-
-            if (mMode == MODE_TRANSPORT_STREAM) {
-                if (followsDiscontinuity) {
-                    mTSParser->signalDiscontinuity(
-                            ATSParser::DISCONTINUITY_TIME, NULL /* extra */);
-                }
-
-                for (size_t offset = 0;
-                        offset < accessUnit->size(); offset += 188) {
-                    status_t err = mTSParser->feedTSPacket(
-                             accessUnit->data() + offset, 188);
-
-                    if (err != OK) {
-                        notifyError(err);
-                        break;
-                    }
-                }
-
-                drainPackets(0 /* trackIndex */, ATSParser::VIDEO);
-                drainPackets(1 /* trackIndex */, ATSParser::AUDIO);
-            } else {
-                postAccessUnit(trackIndex, accessUnit, NULL);
-            }
-            break;
-        }
-
-        case RTPReceiver::kWhatPacketLost:
-        {
-            notifyPacketLost();
-            break;
-        }
-
-        default:
-            TRESPASS();
-    }
-}
-
-void MediaReceiver::drainPackets(
-        size_t trackIndex, ATSParser::SourceType type) {
-    sp<AnotherPacketSource> source =
-        static_cast<AnotherPacketSource *>(
-                mTSParser->getSource(type).get());
-
-    if (source == NULL) {
-        return;
-    }
-
-    sp<AMessage> format;
-    if (!(mFormatKnownMask & (1ul << trackIndex))) {
-        sp<MetaData> meta = source->getFormat();
-        CHECK(meta != NULL);
-
-        CHECK_EQ((status_t)OK, convertMetaDataToMessage(meta, &format));
-
-        mFormatKnownMask |= 1ul << trackIndex;
-    }
-
-    status_t finalResult;
-    while (source->hasBufferAvailable(&finalResult)) {
-        sp<ABuffer> accessUnit;
-        status_t err = source->dequeueAccessUnit(&accessUnit);
-        if (err == OK) {
-            postAccessUnit(trackIndex, accessUnit, format);
-            format.clear();
-        } else if (err != INFO_DISCONTINUITY) {
-            notifyError(err);
-        }
-    }
-
-    if (finalResult != OK) {
-        notifyError(finalResult);
-    }
-}
-
-void MediaReceiver::notifyInitDone(status_t err) {
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatInitDone);
-    notify->setInt32("err", err);
-    notify->post();
-}
-
-void MediaReceiver::notifyError(status_t err) {
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatError);
-    notify->setInt32("err", err);
-    notify->post();
-}
-
-void MediaReceiver::notifyPacketLost() {
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatPacketLost);
-    notify->post();
-}
-
-void MediaReceiver::postAccessUnit(
-        size_t trackIndex,
-        const sp<ABuffer> &accessUnit,
-        const sp<AMessage> &format) {
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatAccessUnit);
-    notify->setSize("trackIndex", trackIndex);
-    notify->setBuffer("accessUnit", accessUnit);
-
-    if (format != NULL) {
-        notify->setMessage("format", format);
-    }
-
-    notify->post();
-}
-
-status_t MediaReceiver::informSender(
-        size_t trackIndex, const sp<AMessage> &params) {
-    if (trackIndex >= mTrackInfos.size()) {
-        return -ERANGE;
-    }
-
-    TrackInfo *info = &mTrackInfos.editItemAt(trackIndex);
-    return info->mReceiver->informSender(params);
-}
-
-}  // namespace android
-
-
diff --git a/media/libstagefright/wifi-display/MediaReceiver.h b/media/libstagefright/wifi-display/MediaReceiver.h
deleted file mode 100644
index afbb407..0000000
--- a/media/libstagefright/wifi-display/MediaReceiver.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2013, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <media/stagefright/foundation/AHandler.h>
-
-#include "ATSParser.h"
-#include "rtp/RTPReceiver.h"
-
-namespace android {
-
-struct ABuffer;
-struct ANetworkSession;
-struct AMessage;
-struct ATSParser;
-
-// This class facilitates receiving of media data for one or more tracks
-// over RTP. Either a 1:1 track to RTP channel mapping is used or a single
-// RTP channel provides the data for a transport stream that is consequently
-// demuxed and its track's data provided to the observer.
-struct MediaReceiver : public AHandler {
-    enum {
-        kWhatInitDone,
-        kWhatError,
-        kWhatAccessUnit,
-        kWhatPacketLost,
-    };
-
-    MediaReceiver(
-            const sp<ANetworkSession> &netSession,
-            const sp<AMessage> &notify);
-
-    ssize_t addTrack(
-            RTPReceiver::TransportMode rtpMode,
-            RTPReceiver::TransportMode rtcpMode,
-            int32_t *localRTPPort);
-
-    status_t connectTrack(
-            size_t trackIndex,
-            const char *remoteHost,
-            int32_t remoteRTPPort,
-            int32_t remoteRTCPPort);
-
-    enum Mode {
-        MODE_UNDEFINED,
-        MODE_TRANSPORT_STREAM,
-        MODE_TRANSPORT_STREAM_RAW,
-        MODE_ELEMENTARY_STREAMS,
-    };
-    status_t initAsync(Mode mode);
-
-    status_t informSender(size_t trackIndex, const sp<AMessage> &params);
-
-protected:
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-    virtual ~MediaReceiver();
-
-private:
-    enum {
-        kWhatInit,
-        kWhatReceiverNotify,
-    };
-
-    struct TrackInfo {
-        sp<RTPReceiver> mReceiver;
-    };
-
-    sp<ANetworkSession> mNetSession;
-    sp<AMessage> mNotify;
-
-    Mode mMode;
-    int32_t mGeneration;
-
-    Vector<TrackInfo> mTrackInfos;
-
-    status_t mInitStatus;
-    size_t mInitDoneCount;
-
-    sp<ATSParser> mTSParser;
-    uint32_t mFormatKnownMask;
-
-    void onReceiverNotify(const sp<AMessage> &msg);
-
-    void drainPackets(size_t trackIndex, ATSParser::SourceType type);
-
-    void notifyInitDone(status_t err);
-    void notifyError(status_t err);
-    void notifyPacketLost();
-
-    void postAccessUnit(
-            size_t trackIndex,
-            const sp<ABuffer> &accessUnit,
-            const sp<AMessage> &format);
-
-    DISALLOW_EVIL_CONSTRUCTORS(MediaReceiver);
-};
-
-}  // namespace android
-
diff --git a/media/libstagefright/wifi-display/SNTPClient.cpp b/media/libstagefright/wifi-display/SNTPClient.cpp
deleted file mode 100644
index 5c0af6a..0000000
--- a/media/libstagefright/wifi-display/SNTPClient.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright 2013, 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 "SNTPClient.h"
-
-#include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/Utils.h>
-
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-namespace android {
-
-SNTPClient::SNTPClient() {
-}
-
-status_t SNTPClient::requestTime(const char *host) {
-    struct hostent *ent;
-    int64_t requestTimeNTP, requestTimeUs;
-    ssize_t n;
-    int64_t responseTimeUs, responseTimeNTP;
-    int64_t originateTimeNTP, receiveTimeNTP, transmitTimeNTP;
-    int64_t roundTripTimeNTP, clockOffsetNTP;
-
-    status_t err = UNKNOWN_ERROR;
-
-    int s = socket(AF_INET, SOCK_DGRAM, 0);
-
-    if (s < 0) {
-        err = -errno;
-
-        goto bail;
-    }
-
-    ent = gethostbyname(host);
-
-    if (ent == NULL) {
-        err = -ENOENT;
-        goto bail2;
-    }
-
-    struct sockaddr_in hostAddr;
-    memset(hostAddr.sin_zero, 0, sizeof(hostAddr.sin_zero));
-    hostAddr.sin_family = AF_INET;
-    hostAddr.sin_port = htons(kNTPPort);
-    hostAddr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr;
-
-    uint8_t packet[kNTPPacketSize];
-    memset(packet, 0, sizeof(packet));
-
-    packet[0] = kNTPModeClient | (kNTPVersion << 3);
-
-    requestTimeNTP = getNowNTP();
-    requestTimeUs = ALooper::GetNowUs();
-    writeTimeStamp(&packet[kNTPTransmitTimeOffset], requestTimeNTP);
-
-    n = sendto(
-            s, packet, sizeof(packet), 0,
-            (const struct sockaddr *)&hostAddr, sizeof(hostAddr));
-
-    if (n < 0) {
-        err = -errno;
-        goto bail2;
-    }
-
-    memset(packet, 0, sizeof(packet));
-
-    do {
-        n = recv(s, packet, sizeof(packet), 0);
-    } while (n < 0 && errno == EINTR);
-
-    if (n < 0) {
-        err = -errno;
-        goto bail2;
-    }
-
-    responseTimeUs = ALooper::GetNowUs();
-
-    responseTimeNTP = requestTimeNTP + makeNTP(responseTimeUs - requestTimeUs);
-
-    originateTimeNTP = readTimeStamp(&packet[kNTPOriginateTimeOffset]);
-    receiveTimeNTP = readTimeStamp(&packet[kNTPReceiveTimeOffset]);
-    transmitTimeNTP = readTimeStamp(&packet[kNTPTransmitTimeOffset]);
-
-    roundTripTimeNTP =
-        makeNTP(responseTimeUs - requestTimeUs)
-            - (transmitTimeNTP - receiveTimeNTP);
-
-    clockOffsetNTP =
-        ((receiveTimeNTP - originateTimeNTP)
-            + (transmitTimeNTP - responseTimeNTP)) / 2;
-
-    mTimeReferenceNTP = responseTimeNTP + clockOffsetNTP;
-    mTimeReferenceUs = responseTimeUs;
-    mRoundTripTimeNTP = roundTripTimeNTP;
-
-    err = OK;
-
-bail2:
-    close(s);
-    s = -1;
-
-bail:
-    return err;
-}
-
-int64_t SNTPClient::adjustTimeUs(int64_t timeUs) const {
-    uint64_t nowNTP =
-        mTimeReferenceNTP + makeNTP(timeUs - mTimeReferenceUs);
-
-    int64_t nowUs =
-        (nowNTP >> 32) * 1000000ll
-        + ((nowNTP & 0xffffffff) * 1000000ll) / (1ll << 32);
-
-    nowUs -= ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll;
-
-    return nowUs;
-}
-
-// static
-void SNTPClient::writeTimeStamp(uint8_t *dst, uint64_t ntpTime) {
-    *dst++ = (ntpTime >> 56) & 0xff;
-    *dst++ = (ntpTime >> 48) & 0xff;
-    *dst++ = (ntpTime >> 40) & 0xff;
-    *dst++ = (ntpTime >> 32) & 0xff;
-    *dst++ = (ntpTime >> 24) & 0xff;
-    *dst++ = (ntpTime >> 16) & 0xff;
-    *dst++ = (ntpTime >> 8) & 0xff;
-    *dst++ = ntpTime & 0xff;
-}
-
-// static
-uint64_t SNTPClient::readTimeStamp(const uint8_t *dst) {
-    return U64_AT(dst);
-}
-
-// static
-uint64_t SNTPClient::getNowNTP() {
-    struct timeval tv;
-    gettimeofday(&tv, NULL /* time zone */);
-
-    uint64_t nowUs = tv.tv_sec * 1000000ll + tv.tv_usec;
-
-    nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll;
-
-    return makeNTP(nowUs);
-}
-
-// static
-uint64_t SNTPClient::makeNTP(uint64_t deltaUs) {
-    uint64_t hi = deltaUs / 1000000ll;
-    uint64_t lo = ((1ll << 32) * (deltaUs % 1000000ll)) / 1000000ll;
-
-    return (hi << 32) | lo;
-}
-
-}  // namespace android
-
diff --git a/media/libstagefright/wifi-display/SNTPClient.h b/media/libstagefright/wifi-display/SNTPClient.h
deleted file mode 100644
index 967d1fc..0000000
--- a/media/libstagefright/wifi-display/SNTPClient.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2013, 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 SNTP_CLIENT_H_
-
-#define SNTP_CLIENT_H_
-
-#include <media/stagefright/foundation/ABase.h>
-#include <utils/Errors.h>
-
-namespace android {
-
-// Implementation of the SNTP (Simple Network Time Protocol)
-struct SNTPClient {
-    SNTPClient();
-
-    status_t requestTime(const char *host);
-
-    // given a time obtained from ALooper::GetNowUs()
-    // return the number of us elapsed since Jan 1 1970 00:00:00 (UTC).
-    int64_t adjustTimeUs(int64_t timeUs) const;
-
-private:
-    enum {
-        kNTPPort = 123,
-        kNTPPacketSize = 48,
-        kNTPModeClient = 3,
-        kNTPVersion = 3,
-        kNTPTransmitTimeOffset = 40,
-        kNTPOriginateTimeOffset = 24,
-        kNTPReceiveTimeOffset = 32,
-    };
-
-    uint64_t mTimeReferenceNTP;
-    int64_t mTimeReferenceUs;
-    int64_t mRoundTripTimeNTP;
-
-    static void writeTimeStamp(uint8_t *dst, uint64_t ntpTime);
-    static uint64_t readTimeStamp(const uint8_t *dst);
-
-    static uint64_t getNowNTP();
-    static uint64_t makeNTP(uint64_t deltaUs);
-
-    DISALLOW_EVIL_CONSTRUCTORS(SNTPClient);
-};
-
-}  // namespace android
-
-#endif  // SNTP_CLIENT_H_
diff --git a/media/libstagefright/wifi-display/TimeSyncer.cpp b/media/libstagefright/wifi-display/TimeSyncer.cpp
deleted file mode 100644
index 0f4d93a..0000000
--- a/media/libstagefright/wifi-display/TimeSyncer.cpp
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright 2013, 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_NEBUG 0
-#define LOG_TAG "TimeSyncer"
-#include <utils/Log.h>
-
-#include "TimeSyncer.h"
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AHandler.h>
-#include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/ANetworkSession.h>
-#include <media/stagefright/Utils.h>
-
-namespace android {
-
-TimeSyncer::TimeSyncer(
-        const sp<ANetworkSession> &netSession, const sp<AMessage> &notify)
-    : mNetSession(netSession),
-      mNotify(notify),
-      mIsServer(false),
-      mConnected(false),
-      mUDPSession(0),
-      mSeqNo(0),
-      mTotalTimeUs(0.0),
-      mPendingT1(0ll),
-      mTimeoutGeneration(0) {
-}
-
-TimeSyncer::~TimeSyncer() {
-}
-
-void TimeSyncer::startServer(unsigned localPort) {
-    sp<AMessage> msg = new AMessage(kWhatStartServer, id());
-    msg->setInt32("localPort", localPort);
-    msg->post();
-}
-
-void TimeSyncer::startClient(const char *remoteHost, unsigned remotePort) {
-    sp<AMessage> msg = new AMessage(kWhatStartClient, id());
-    msg->setString("remoteHost", remoteHost);
-    msg->setInt32("remotePort", remotePort);
-    msg->post();
-}
-
-void TimeSyncer::onMessageReceived(const sp<AMessage> &msg) {
-    switch (msg->what()) {
-        case kWhatStartClient:
-        {
-            AString remoteHost;
-            CHECK(msg->findString("remoteHost", &remoteHost));
-
-            int32_t remotePort;
-            CHECK(msg->findInt32("remotePort", &remotePort));
-
-            sp<AMessage> notify = new AMessage(kWhatUDPNotify, id());
-
-            CHECK_EQ((status_t)OK,
-                     mNetSession->createUDPSession(
-                         0 /* localPort */,
-                         remoteHost.c_str(),
-                         remotePort,
-                         notify,
-                         &mUDPSession));
-
-            postSendPacket();
-            break;
-        }
-
-        case kWhatStartServer:
-        {
-            mIsServer = true;
-
-            int32_t localPort;
-            CHECK(msg->findInt32("localPort", &localPort));
-
-            sp<AMessage> notify = new AMessage(kWhatUDPNotify, id());
-
-            CHECK_EQ((status_t)OK,
-                     mNetSession->createUDPSession(
-                         localPort, notify, &mUDPSession));
-
-            break;
-        }
-
-        case kWhatSendPacket:
-        {
-            if (mHistory.size() == 0) {
-                ALOGI("starting batch");
-            }
-
-            TimeInfo ti;
-            memset(&ti, 0, sizeof(ti));
-
-            ti.mT1 = ALooper::GetNowUs();
-
-            CHECK_EQ((status_t)OK,
-                     mNetSession->sendRequest(
-                         mUDPSession, &ti, sizeof(ti)));
-
-            mPendingT1 = ti.mT1;
-            postTimeout();
-            break;
-        }
-
-        case kWhatTimedOut:
-        {
-            int32_t generation;
-            CHECK(msg->findInt32("generation", &generation));
-
-            if (generation != mTimeoutGeneration) {
-                break;
-            }
-
-            ALOGI("timed out, sending another request");
-            postSendPacket();
-            break;
-        }
-
-        case kWhatUDPNotify:
-        {
-            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);
-
-                    cancelTimeout();
-
-                    notifyError(err);
-                    break;
-                }
-
-                case ANetworkSession::kWhatDatagram:
-                {
-                    int32_t sessionID;
-                    CHECK(msg->findInt32("sessionID", &sessionID));
-
-                    sp<ABuffer> packet;
-                    CHECK(msg->findBuffer("data", &packet));
-
-                    int64_t arrivalTimeUs;
-                    CHECK(packet->meta()->findInt64(
-                                "arrivalTimeUs", &arrivalTimeUs));
-
-                    CHECK_EQ(packet->size(), sizeof(TimeInfo));
-
-                    TimeInfo *ti = (TimeInfo *)packet->data();
-
-                    if (mIsServer) {
-                        if (!mConnected) {
-                            AString fromAddr;
-                            CHECK(msg->findString("fromAddr", &fromAddr));
-
-                            int32_t fromPort;
-                            CHECK(msg->findInt32("fromPort", &fromPort));
-
-                            CHECK_EQ((status_t)OK,
-                                     mNetSession->connectUDPSession(
-                                         mUDPSession, fromAddr.c_str(), fromPort));
-
-                            mConnected = true;
-                        }
-
-                        ti->mT2 = arrivalTimeUs;
-                        ti->mT3 = ALooper::GetNowUs();
-
-                        CHECK_EQ((status_t)OK,
-                                 mNetSession->sendRequest(
-                                     mUDPSession, ti, sizeof(*ti)));
-                    } else {
-                        if (ti->mT1 != mPendingT1) {
-                            break;
-                        }
-
-                        cancelTimeout();
-                        mPendingT1 = 0;
-
-                        ti->mT4 = arrivalTimeUs;
-
-                        // One way delay for a packet to travel from client
-                        // to server or back (assumed to be the same either way).
-                        int64_t delay =
-                            (ti->mT2 - ti->mT1 + ti->mT4 - ti->mT3) / 2;
-
-                        // Offset between the client clock (T1, T4) and the
-                        // server clock (T2, T3) timestamps.
-                        int64_t offset =
-                            (ti->mT2 - ti->mT1 - ti->mT4 + ti->mT3) / 2;
-
-                        mHistory.push_back(*ti);
-
-                        ALOGV("delay = %lld us,\toffset %lld us",
-                               delay,
-                               offset);
-
-                        if (mHistory.size() < kNumPacketsPerBatch) {
-                            postSendPacket(1000000ll / 30);
-                        } else {
-                            notifyOffset();
-
-                            ALOGI("batch done");
-
-                            mHistory.clear();
-                            postSendPacket(kBatchDelayUs);
-                        }
-                    }
-                    break;
-                }
-
-                default:
-                    TRESPASS();
-            }
-
-            break;
-        }
-
-        default:
-            TRESPASS();
-    }
-}
-
-void TimeSyncer::postSendPacket(int64_t delayUs) {
-    (new AMessage(kWhatSendPacket, id()))->post(delayUs);
-}
-
-void TimeSyncer::postTimeout() {
-    sp<AMessage> msg = new AMessage(kWhatTimedOut, id());
-    msg->setInt32("generation", mTimeoutGeneration);
-    msg->post(kTimeoutDelayUs);
-}
-
-void TimeSyncer::cancelTimeout() {
-    ++mTimeoutGeneration;
-}
-
-void TimeSyncer::notifyError(status_t err) {
-    if (mNotify == NULL) {
-        looper()->stop();
-        return;
-    }
-
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatError);
-    notify->setInt32("err", err);
-    notify->post();
-}
-
-// static
-int TimeSyncer::CompareRountripTime(const TimeInfo *ti1, const TimeInfo *ti2) {
-    int64_t rt1 = ti1->mT4 - ti1->mT1;
-    int64_t rt2 = ti2->mT4 - ti2->mT1;
-
-    if (rt1 < rt2) {
-        return -1;
-    } else if (rt1 > rt2) {
-        return 1;
-    }
-
-    return 0;
-}
-
-void TimeSyncer::notifyOffset() {
-    mHistory.sort(CompareRountripTime);
-
-    int64_t sum = 0ll;
-    size_t count = 0;
-
-    // Only consider the third of the information associated with the best
-    // (smallest) roundtrip times.
-    for (size_t i = 0; i < mHistory.size() / 3; ++i) {
-        const TimeInfo *ti = &mHistory[i];
-
-#if 0
-        // One way delay for a packet to travel from client
-        // to server or back (assumed to be the same either way).
-        int64_t delay =
-            (ti->mT2 - ti->mT1 + ti->mT4 - ti->mT3) / 2;
-#endif
-
-        // Offset between the client clock (T1, T4) and the
-        // server clock (T2, T3) timestamps.
-        int64_t offset =
-            (ti->mT2 - ti->mT1 - ti->mT4 + ti->mT3) / 2;
-
-        ALOGV("(%d) RT: %lld us, offset: %lld us",
-              i, ti->mT4 - ti->mT1, offset);
-
-        sum += offset;
-        ++count;
-    }
-
-    if (mNotify == NULL) {
-        ALOGI("avg. offset is %lld", sum / count);
-        return;
-    }
-
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatTimeOffset);
-    notify->setInt64("offset", sum / count);
-    notify->post();
-}
-
-}  // namespace android
diff --git a/media/libstagefright/wifi-display/TimeSyncer.h b/media/libstagefright/wifi-display/TimeSyncer.h
deleted file mode 100644
index 4e7571f..0000000
--- a/media/libstagefright/wifi-display/TimeSyncer.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright 2013, 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 TIME_SYNCER_H_
-
-#define TIME_SYNCER_H_
-
-#include <media/stagefright/foundation/AHandler.h>
-
-namespace android {
-
-struct ANetworkSession;
-
-/*
-   TimeSyncer allows us to synchronize time between a client and a server.
-   The client sends a UDP packet containing its send-time to the server,
-   the server sends that packet back to the client amended with information
-   about when it was received as well as the time the reply was sent back.
-   Finally the client receives the reply and has now enough information to
-   compute the clock offset between client and server assuming that packet
-   exchange is symmetric, i.e. time for a packet client->server and
-   server->client is roughly equal.
-   This exchange is repeated a number of times and the average offset computed
-   over the 30% of packets that had the lowest roundtrip times.
-   The offset is determined every 10 secs to account for slight differences in
-   clock frequency.
-*/
-struct TimeSyncer : public AHandler {
-    enum {
-        kWhatError,
-        kWhatTimeOffset,
-    };
-    TimeSyncer(
-            const sp<ANetworkSession> &netSession,
-            const sp<AMessage> &notify);
-
-    void startServer(unsigned localPort);
-    void startClient(const char *remoteHost, unsigned remotePort);
-
-protected:
-    virtual ~TimeSyncer();
-
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
-    enum {
-        kWhatStartServer,
-        kWhatStartClient,
-        kWhatUDPNotify,
-        kWhatSendPacket,
-        kWhatTimedOut,
-    };
-
-    struct TimeInfo {
-        int64_t mT1;  // client timestamp at send
-        int64_t mT2;  // server timestamp at receive
-        int64_t mT3;  // server timestamp at send
-        int64_t mT4;  // client timestamp at receive
-    };
-
-    enum {
-        kNumPacketsPerBatch = 30,
-    };
-    static const int64_t kTimeoutDelayUs = 500000ll;
-    static const int64_t kBatchDelayUs = 60000000ll;  // every minute
-
-    sp<ANetworkSession> mNetSession;
-    sp<AMessage> mNotify;
-
-    bool mIsServer;
-    bool mConnected;
-    int32_t mUDPSession;
-    uint32_t mSeqNo;
-    double mTotalTimeUs;
-
-    Vector<TimeInfo> mHistory;
-
-    int64_t mPendingT1;
-    int32_t mTimeoutGeneration;
-
-    void postSendPacket(int64_t delayUs = 0ll);
-
-    void postTimeout();
-    void cancelTimeout();
-
-    void notifyError(status_t err);
-    void notifyOffset();
-
-    static int CompareRountripTime(const TimeInfo *ti1, const TimeInfo *ti2);
-
-    DISALLOW_EVIL_CONSTRUCTORS(TimeSyncer);
-};
-
-}  // namespace android
-
-#endif  // TIME_SYNCER_H_
diff --git a/media/libstagefright/wifi-display/nettest.cpp b/media/libstagefright/wifi-display/nettest.cpp
deleted file mode 100644
index 73c0d80..0000000
--- a/media/libstagefright/wifi-display/nettest.cpp
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * Copyright 2013, 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_NEBUG 0
-#define LOG_TAG "nettest"
-#include <utils/Log.h>
-
-#include "TimeSyncer.h"
-
-#include <binder/ProcessState.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AHandler.h>
-#include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/ANetworkSession.h>
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/DataSource.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/NuMediaExtractor.h>
-#include <media/stagefright/Utils.h>
-
-namespace android {
-
-struct TestHandler : public AHandler {
-    TestHandler(const sp<ANetworkSession> &netSession);
-
-    void listen(int32_t port);
-    void connect(const char *host, int32_t port);
-
-protected:
-    virtual ~TestHandler();
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
-    enum {
-        kTimeSyncerPort = 8123,
-    };
-
-    enum {
-        kWhatListen,
-        kWhatConnect,
-        kWhatTimeSyncerNotify,
-        kWhatNetNotify,
-        kWhatSendMore,
-        kWhatStop,
-    };
-
-    sp<ANetworkSession> mNetSession;
-    sp<TimeSyncer> mTimeSyncer;
-
-    int32_t mServerSessionID;
-    int32_t mSessionID;
-
-    int64_t mTimeOffsetUs;
-    bool mTimeOffsetValid;
-
-    int32_t mCounter;
-
-    int64_t mMaxDelayMs;
-
-    void dumpDelay(int32_t counter, int64_t delayMs);
-
-    DISALLOW_EVIL_CONSTRUCTORS(TestHandler);
-};
-
-TestHandler::TestHandler(const sp<ANetworkSession> &netSession)
-    : mNetSession(netSession),
-      mServerSessionID(0),
-      mSessionID(0),
-      mTimeOffsetUs(-1ll),
-      mTimeOffsetValid(false),
-      mCounter(0),
-      mMaxDelayMs(-1ll) {
-}
-
-TestHandler::~TestHandler() {
-}
-
-void TestHandler::listen(int32_t port) {
-    sp<AMessage> msg = new AMessage(kWhatListen, id());
-    msg->setInt32("port", port);
-    msg->post();
-}
-
-void TestHandler::connect(const char *host, int32_t port) {
-    sp<AMessage> msg = new AMessage(kWhatConnect, id());
-    msg->setString("host", host);
-    msg->setInt32("port", port);
-    msg->post();
-}
-
-void TestHandler::dumpDelay(int32_t counter, int64_t delayMs) {
-    static const int64_t kMinDelayMs = 0;
-    static const int64_t kMaxDelayMs = 300;
-
-    const char *kPattern = "########################################";
-    size_t kPatternSize = strlen(kPattern);
-
-    int n = (kPatternSize * (delayMs - kMinDelayMs))
-                / (kMaxDelayMs - kMinDelayMs);
-
-    if (n < 0) {
-        n = 0;
-    } else if ((size_t)n > kPatternSize) {
-        n = kPatternSize;
-    }
-
-    if (delayMs > mMaxDelayMs) {
-        mMaxDelayMs = delayMs;
-    }
-
-    ALOGI("[%d] (%4lld ms / %4lld ms) %s",
-          counter,
-          delayMs,
-          mMaxDelayMs,
-          kPattern + kPatternSize - n);
-}
-
-void TestHandler::onMessageReceived(const sp<AMessage> &msg) {
-    switch (msg->what()) {
-        case kWhatListen:
-        {
-            sp<AMessage> notify = new AMessage(kWhatTimeSyncerNotify, id());
-            mTimeSyncer = new TimeSyncer(mNetSession, notify);
-            looper()->registerHandler(mTimeSyncer);
-
-            notify = new AMessage(kWhatNetNotify, id());
-
-            int32_t port;
-            CHECK(msg->findInt32("port", &port));
-
-            struct in_addr ifaceAddr;
-            ifaceAddr.s_addr = INADDR_ANY;
-
-            CHECK_EQ((status_t)OK,
-                     mNetSession->createTCPDatagramSession(
-                         ifaceAddr,
-                         port,
-                         notify,
-                         &mServerSessionID));
-            break;
-        }
-
-        case kWhatConnect:
-        {
-            sp<AMessage> notify = new AMessage(kWhatTimeSyncerNotify, id());
-            mTimeSyncer = new TimeSyncer(mNetSession, notify);
-            looper()->registerHandler(mTimeSyncer);
-            mTimeSyncer->startServer(kTimeSyncerPort);
-
-            AString host;
-            CHECK(msg->findString("host", &host));
-
-            int32_t port;
-            CHECK(msg->findInt32("port", &port));
-
-            notify = new AMessage(kWhatNetNotify, id());
-
-            CHECK_EQ((status_t)OK,
-                     mNetSession->createTCPDatagramSession(
-                         0 /* localPort */,
-                         host.c_str(),
-                         port,
-                         notify,
-                         &mSessionID));
-            break;
-        }
-
-        case kWhatNetNotify:
-        {
-            int32_t reason;
-            CHECK(msg->findInt32("reason", &reason));
-
-            switch (reason) {
-                case ANetworkSession::kWhatConnected:
-                {
-                    ALOGI("kWhatConnected");
-
-                    (new AMessage(kWhatSendMore, id()))->post();
-                    break;
-                }
-
-                case ANetworkSession::kWhatClientConnected:
-                {
-                    ALOGI("kWhatClientConnected");
-
-                    CHECK_EQ(mSessionID, 0);
-                    CHECK(msg->findInt32("sessionID", &mSessionID));
-
-                    AString clientIP;
-                    CHECK(msg->findString("client-ip", &clientIP));
-
-                    mTimeSyncer->startClient(clientIP.c_str(), kTimeSyncerPort);
-                    break;
-                }
-
-                case ANetworkSession::kWhatDatagram:
-                {
-                    sp<ABuffer> packet;
-                    CHECK(msg->findBuffer("data", &packet));
-
-                    CHECK_EQ(packet->size(), 12u);
-
-                    int32_t counter = U32_AT(packet->data());
-                    int64_t timeUs = U64_AT(packet->data() + 4);
-
-                    if (mTimeOffsetValid) {
-                        timeUs -= mTimeOffsetUs;
-                        int64_t nowUs = ALooper::GetNowUs();
-                        int64_t delayMs = (nowUs - timeUs) / 1000ll;
-
-                        dumpDelay(counter, delayMs);
-                    } else {
-                        ALOGI("received %d", counter);
-                    }
-                    break;
-                }
-
-                case ANetworkSession::kWhatError:
-                {
-                    ALOGE("kWhatError");
-                    break;
-                }
-
-                default:
-                    TRESPASS();
-            }
-            break;
-        }
-
-        case kWhatTimeSyncerNotify:
-        {
-            CHECK(msg->findInt64("offset", &mTimeOffsetUs));
-            mTimeOffsetValid = true;
-            break;
-        }
-
-        case kWhatSendMore:
-        {
-            uint8_t buffer[4 + 8];
-            buffer[0] = mCounter >> 24;
-            buffer[1] = (mCounter >> 16) & 0xff;
-            buffer[2] = (mCounter >> 8) & 0xff;
-            buffer[3] = mCounter & 0xff;
-
-            int64_t nowUs = ALooper::GetNowUs();
-
-            buffer[4] = nowUs >> 56;
-            buffer[5] = (nowUs >> 48) & 0xff;
-            buffer[6] = (nowUs >> 40) & 0xff;
-            buffer[7] = (nowUs >> 32) & 0xff;
-            buffer[8] = (nowUs >> 24) & 0xff;
-            buffer[9] = (nowUs >> 16) & 0xff;
-            buffer[10] = (nowUs >> 8) & 0xff;
-            buffer[11] = nowUs & 0xff;
-
-            ++mCounter;
-
-            CHECK_EQ((status_t)OK,
-                     mNetSession->sendRequest(
-                         mSessionID,
-                         buffer,
-                         sizeof(buffer),
-                         true /* timeValid */,
-                         nowUs));
-
-            msg->post(100000ll);
-            break;
-        }
-
-        case kWhatStop:
-        {
-            if (mSessionID != 0) {
-                mNetSession->destroySession(mSessionID);
-                mSessionID = 0;
-            }
-
-            if (mServerSessionID != 0) {
-                mNetSession->destroySession(mServerSessionID);
-                mServerSessionID = 0;
-            }
-
-            looper()->stop();
-            break;
-        }
-
-        default:
-            TRESPASS();
-    }
-}
-
-}  // namespace android
-
-static void usage(const char *me) {
-    fprintf(stderr,
-            "usage: %s -c host:port\tconnect to remote host\n"
-            "               -l port   \tlisten\n",
-            me);
-}
-
-int main(int argc, char **argv) {
-    using namespace android;
-
-    // srand(time(NULL));
-
-    ProcessState::self()->startThreadPool();
-
-    DataSource::RegisterDefaultSniffers();
-
-    int32_t connectToPort = -1;
-    AString connectToHost;
-
-    int32_t listenOnPort = -1;
-
-    int res;
-    while ((res = getopt(argc, argv, "hc:l:")) >= 0) {
-        switch (res) {
-            case 'c':
-            {
-                const char *colonPos = strrchr(optarg, ':');
-
-                if (colonPos == NULL) {
-                    usage(argv[0]);
-                    exit(1);
-                }
-
-                connectToHost.setTo(optarg, colonPos - optarg);
-
-                char *end;
-                connectToPort = strtol(colonPos + 1, &end, 10);
-
-                if (*end != '\0' || end == colonPos + 1
-                        || connectToPort < 0 || connectToPort > 65535) {
-                    fprintf(stderr, "Illegal port specified.\n");
-                    exit(1);
-                }
-                break;
-            }
-
-            case 'l':
-            {
-                char *end;
-                listenOnPort = strtol(optarg, &end, 10);
-
-                if (*end != '\0' || end == optarg
-                        || listenOnPort < 0 || listenOnPort > 65535) {
-                    fprintf(stderr, "Illegal port specified.\n");
-                    exit(1);
-                }
-                break;
-            }
-
-            case '?':
-            case 'h':
-                usage(argv[0]);
-                exit(1);
-        }
-    }
-
-    if ((listenOnPort < 0 && connectToPort < 0)
-            || (listenOnPort >= 0 && connectToPort >= 0)) {
-        fprintf(stderr,
-                "You need to select either client or server mode.\n");
-        exit(1);
-    }
-
-    sp<ANetworkSession> netSession = new ANetworkSession;
-    netSession->start();
-
-    sp<ALooper> looper = new ALooper;
-
-    sp<TestHandler> handler = new TestHandler(netSession);
-    looper->registerHandler(handler);
-
-    if (listenOnPort) {
-        handler->listen(listenOnPort);
-    }
-
-    if (connectToPort >= 0) {
-        handler->connect(connectToHost.c_str(), connectToPort);
-    }
-
-    looper->start(true /* runOnCallingThread */);
-
-    return 0;
-}
diff --git a/media/libstagefright/wifi-display/rtp/RTPAssembler.cpp b/media/libstagefright/wifi-display/rtp/RTPAssembler.cpp
deleted file mode 100644
index 7a96081..0000000
--- a/media/libstagefright/wifi-display/rtp/RTPAssembler.cpp
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Copyright 2013, 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 "RTPAssembler"
-#include <utils/Log.h>
-
-#include "RTPAssembler.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/MediaErrors.h>
-
-namespace android {
-
-RTPReceiver::Assembler::Assembler(const sp<AMessage> &notify)
-    : mNotify(notify) {
-}
-
-void RTPReceiver::Assembler::postAccessUnit(
-        const sp<ABuffer> &accessUnit, bool followsDiscontinuity) {
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", RTPReceiver::kWhatAccessUnit);
-    notify->setBuffer("accessUnit", accessUnit);
-    notify->setInt32("followsDiscontinuity", followsDiscontinuity);
-    notify->post();
-}
-////////////////////////////////////////////////////////////////////////////////
-
-RTPReceiver::TSAssembler::TSAssembler(const sp<AMessage> &notify)
-    : Assembler(notify),
-      mSawDiscontinuity(false) {
-}
-
-void RTPReceiver::TSAssembler::signalDiscontinuity() {
-    mSawDiscontinuity = true;
-}
-
-status_t RTPReceiver::TSAssembler::processPacket(const sp<ABuffer> &packet) {
-    int32_t rtpTime;
-    CHECK(packet->meta()->findInt32("rtp-time", &rtpTime));
-
-    packet->meta()->setInt64("timeUs", (rtpTime * 100ll) / 9);
-
-    postAccessUnit(packet, mSawDiscontinuity);
-
-    if (mSawDiscontinuity) {
-        mSawDiscontinuity = false;
-    }
-
-    return OK;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-RTPReceiver::H264Assembler::H264Assembler(const sp<AMessage> &notify)
-    : Assembler(notify),
-      mState(0),
-      mIndicator(0),
-      mNALType(0),
-      mAccessUnitRTPTime(0) {
-}
-
-void RTPReceiver::H264Assembler::signalDiscontinuity() {
-    reset();
-}
-
-status_t RTPReceiver::H264Assembler::processPacket(const sp<ABuffer> &packet) {
-    status_t err = internalProcessPacket(packet);
-
-    if (err != OK) {
-        reset();
-    }
-
-    return err;
-}
-
-status_t RTPReceiver::H264Assembler::internalProcessPacket(
-        const sp<ABuffer> &packet) {
-    const uint8_t *data = packet->data();
-    size_t size = packet->size();
-
-    switch (mState) {
-        case 0:
-        {
-            if (size < 1 || (data[0] & 0x80)) {
-                ALOGV("Malformed H264 RTP packet (empty or F-bit set)");
-                return ERROR_MALFORMED;
-            }
-
-            unsigned nalType = data[0] & 0x1f;
-            if (nalType >= 1 && nalType <= 23) {
-                addSingleNALUnit(packet);
-                ALOGV("added single NAL packet");
-            } else if (nalType == 28) {
-                // FU-A
-                unsigned indicator = data[0];
-                CHECK((indicator & 0x1f) == 28);
-
-                if (size < 2) {
-                    ALOGV("Malformed H264 FU-A packet (single byte)");
-                    return ERROR_MALFORMED;
-                }
-
-                if (!(data[1] & 0x80)) {
-                    ALOGV("Malformed H264 FU-A packet (no start bit)");
-                    return ERROR_MALFORMED;
-                }
-
-                mIndicator = data[0];
-                mNALType = data[1] & 0x1f;
-                uint32_t nri = (data[0] >> 5) & 3;
-
-                clearAccumulator();
-
-                uint8_t byte = mNALType | (nri << 5);
-                appendToAccumulator(&byte, 1);
-                appendToAccumulator(data + 2, size - 2);
-
-                int32_t rtpTime;
-                CHECK(packet->meta()->findInt32("rtp-time", &rtpTime));
-                mAccumulator->meta()->setInt32("rtp-time", rtpTime);
-
-                if (data[1] & 0x40) {
-                    // Huh? End bit also set on the first buffer.
-                    addSingleNALUnit(mAccumulator);
-                    clearAccumulator();
-
-                    ALOGV("added FU-A");
-                    break;
-                }
-
-                mState = 1;
-            } else if (nalType == 24) {
-                // STAP-A
-
-                status_t err = addSingleTimeAggregationPacket(packet);
-                if (err != OK) {
-                    return err;
-                }
-            } else {
-                ALOGV("Malformed H264 packet (unknown type %d)", nalType);
-                return ERROR_UNSUPPORTED;
-            }
-            break;
-        }
-
-        case 1:
-        {
-            if (size < 2
-                    || data[0] != mIndicator
-                    || (data[1] & 0x1f) != mNALType
-                    || (data[1] & 0x80)) {
-                ALOGV("Malformed H264 FU-A packet (indicator, "
-                      "type or start bit mismatch)");
-
-                return ERROR_MALFORMED;
-            }
-
-            appendToAccumulator(data + 2, size - 2);
-
-            if (data[1] & 0x40) {
-                addSingleNALUnit(mAccumulator);
-
-                clearAccumulator();
-                mState = 0;
-
-                ALOGV("added FU-A");
-            }
-            break;
-        }
-
-        default:
-            TRESPASS();
-    }
-
-    int32_t marker;
-    CHECK(packet->meta()->findInt32("M", &marker));
-
-    if (marker) {
-        flushAccessUnit();
-    }
-
-    return OK;
-}
-
-void RTPReceiver::H264Assembler::reset() {
-    mNALUnits.clear();
-
-    clearAccumulator();
-    mState = 0;
-}
-
-void RTPReceiver::H264Assembler::clearAccumulator() {
-    if (mAccumulator != NULL) {
-        // XXX Too expensive.
-        mAccumulator.clear();
-    }
-}
-
-void RTPReceiver::H264Assembler::appendToAccumulator(
-        const void *data, size_t size) {
-    if (mAccumulator == NULL) {
-        mAccumulator = new ABuffer(size);
-        memcpy(mAccumulator->data(), data, size);
-        return;
-    }
-
-    if (mAccumulator->size() + size > mAccumulator->capacity()) {
-        sp<ABuffer> buf = new ABuffer(mAccumulator->size() + size);
-        memcpy(buf->data(), mAccumulator->data(), mAccumulator->size());
-        buf->setRange(0, mAccumulator->size());
-
-        int32_t rtpTime;
-        if (mAccumulator->meta()->findInt32("rtp-time", &rtpTime)) {
-            buf->meta()->setInt32("rtp-time", rtpTime);
-        }
-
-        mAccumulator = buf;
-    }
-
-    memcpy(mAccumulator->data() + mAccumulator->size(), data, size);
-    mAccumulator->setRange(0, mAccumulator->size() + size);
-}
-
-void RTPReceiver::H264Assembler::addSingleNALUnit(const sp<ABuffer> &packet) {
-    if (mNALUnits.empty()) {
-        int32_t rtpTime;
-        CHECK(packet->meta()->findInt32("rtp-time", &rtpTime));
-
-        mAccessUnitRTPTime = rtpTime;
-    }
-
-    mNALUnits.push_back(packet);
-}
-
-void RTPReceiver::H264Assembler::flushAccessUnit() {
-    if (mNALUnits.empty()) {
-        return;
-    }
-
-    size_t totalSize = 0;
-    for (List<sp<ABuffer> >::iterator it = mNALUnits.begin();
-            it != mNALUnits.end(); ++it) {
-        totalSize += 4 + (*it)->size();
-    }
-
-    sp<ABuffer> accessUnit = new ABuffer(totalSize);
-    size_t offset = 0;
-    for (List<sp<ABuffer> >::iterator it = mNALUnits.begin();
-            it != mNALUnits.end(); ++it) {
-        const sp<ABuffer> nalUnit = *it;
-
-        memcpy(accessUnit->data() + offset, "\x00\x00\x00\x01", 4);
-
-        memcpy(accessUnit->data() + offset + 4,
-               nalUnit->data(),
-               nalUnit->size());
-
-        offset += 4 + nalUnit->size();
-    }
-
-    mNALUnits.clear();
-
-    accessUnit->meta()->setInt64("timeUs", mAccessUnitRTPTime * 100ll / 9ll);
-    postAccessUnit(accessUnit, false /* followsDiscontinuity */);
-}
-
-status_t RTPReceiver::H264Assembler::addSingleTimeAggregationPacket(
-        const sp<ABuffer> &packet) {
-    const uint8_t *data = packet->data();
-    size_t size = packet->size();
-
-    if (size < 3) {
-        ALOGV("Malformed H264 STAP-A packet (too small)");
-        return ERROR_MALFORMED;
-    }
-
-    int32_t rtpTime;
-    CHECK(packet->meta()->findInt32("rtp-time", &rtpTime));
-
-    ++data;
-    --size;
-    while (size >= 2) {
-        size_t nalSize = (data[0] << 8) | data[1];
-
-        if (size < nalSize + 2) {
-            ALOGV("Malformed H264 STAP-A packet (incomplete NAL unit)");
-            return ERROR_MALFORMED;
-        }
-
-        sp<ABuffer> unit = new ABuffer(nalSize);
-        memcpy(unit->data(), &data[2], nalSize);
-
-        unit->meta()->setInt32("rtp-time", rtpTime);
-
-        addSingleNALUnit(unit);
-
-        data += 2 + nalSize;
-        size -= 2 + nalSize;
-    }
-
-    if (size != 0) {
-        ALOGV("Unexpected padding at end of STAP-A packet.");
-    }
-
-    ALOGV("added STAP-A");
-
-    return OK;
-}
-
-}  // namespace android
-
diff --git a/media/libstagefright/wifi-display/rtp/RTPAssembler.h b/media/libstagefright/wifi-display/rtp/RTPAssembler.h
deleted file mode 100644
index e456d32..0000000
--- a/media/libstagefright/wifi-display/rtp/RTPAssembler.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright 2013, 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 RTP_ASSEMBLER_H_
-
-#define RTP_ASSEMBLER_H_
-
-#include "RTPReceiver.h"
-
-namespace android {
-
-// A helper class to reassemble the payload of RTP packets into access
-// units depending on the packetization scheme.
-struct RTPReceiver::Assembler : public RefBase {
-    Assembler(const sp<AMessage> &notify);
-
-    virtual void signalDiscontinuity() = 0;
-    virtual status_t processPacket(const sp<ABuffer> &packet) = 0;
-
-protected:
-    virtual ~Assembler() {}
-
-    void postAccessUnit(
-            const sp<ABuffer> &accessUnit, bool followsDiscontinuity);
-
-private:
-    sp<AMessage> mNotify;
-
-    DISALLOW_EVIL_CONSTRUCTORS(Assembler);
-};
-
-struct RTPReceiver::TSAssembler : public RTPReceiver::Assembler {
-    TSAssembler(const sp<AMessage> &notify);
-
-    virtual void signalDiscontinuity();
-    virtual status_t processPacket(const sp<ABuffer> &packet);
-
-private:
-    bool mSawDiscontinuity;
-
-    DISALLOW_EVIL_CONSTRUCTORS(TSAssembler);
-};
-
-struct RTPReceiver::H264Assembler : public RTPReceiver::Assembler {
-    H264Assembler(const sp<AMessage> &notify);
-
-    virtual void signalDiscontinuity();
-    virtual status_t processPacket(const sp<ABuffer> &packet);
-
-private:
-    int32_t mState;
-
-    uint8_t mIndicator;
-    uint8_t mNALType;
-
-    sp<ABuffer> mAccumulator;
-
-    List<sp<ABuffer> > mNALUnits;
-    int32_t mAccessUnitRTPTime;
-
-    status_t internalProcessPacket(const sp<ABuffer> &packet);
-
-    void addSingleNALUnit(const sp<ABuffer> &packet);
-    status_t addSingleTimeAggregationPacket(const sp<ABuffer> &packet);
-
-    void flushAccessUnit();
-
-    void clearAccumulator();
-    void appendToAccumulator(const void *data, size_t size);
-
-    void reset();
-
-    DISALLOW_EVIL_CONSTRUCTORS(H264Assembler);
-};
-
-}  // namespace android
-
-#endif  // RTP_ASSEMBLER_H_
-
diff --git a/media/libstagefright/wifi-display/rtp/RTPReceiver.cpp b/media/libstagefright/wifi-display/rtp/RTPReceiver.cpp
deleted file mode 100644
index 3b3bd63..0000000
--- a/media/libstagefright/wifi-display/rtp/RTPReceiver.cpp
+++ /dev/null
@@ -1,1152 +0,0 @@
-/*
- * Copyright 2013, 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 "RTPReceiver"
-#include <utils/Log.h>
-
-#include "RTPAssembler.h"
-#include "RTPReceiver.h"
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/ANetworkSession.h>
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/Utils.h>
-
-#define TRACK_PACKET_LOSS       0
-
-namespace android {
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct RTPReceiver::Source : public AHandler {
-    Source(RTPReceiver *receiver, uint32_t ssrc);
-
-    void onPacketReceived(uint16_t seq, const sp<ABuffer> &buffer);
-
-    void addReportBlock(uint32_t ssrc, const sp<ABuffer> &buf);
-
-protected:
-    virtual ~Source();
-
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
-    enum {
-        kWhatRetransmit,
-        kWhatDeclareLost,
-    };
-
-    static const uint32_t kMinSequential = 2;
-    static const uint32_t kMaxDropout = 3000;
-    static const uint32_t kMaxMisorder = 100;
-    static const uint32_t kRTPSeqMod = 1u << 16;
-    static const int64_t kReportIntervalUs = 10000000ll;
-
-    RTPReceiver *mReceiver;
-    uint32_t mSSRC;
-    bool mFirst;
-    uint16_t mMaxSeq;
-    uint32_t mCycles;
-    uint32_t mBaseSeq;
-    uint32_t mReceived;
-    uint32_t mExpectedPrior;
-    uint32_t mReceivedPrior;
-
-    int64_t mFirstArrivalTimeUs;
-    int64_t mFirstRTPTimeUs;
-
-    // Ordered by extended seq number.
-    List<sp<ABuffer> > mPackets;
-
-    enum StatusBits {
-        STATUS_DECLARED_LOST            = 1,
-        STATUS_REQUESTED_RETRANSMISSION = 2,
-        STATUS_ARRIVED_LATE             = 4,
-    };
-#if TRACK_PACKET_LOSS
-    KeyedVector<int32_t, uint32_t> mLostPackets;
-#endif
-
-    void modifyPacketStatus(int32_t extSeqNo, uint32_t mask);
-
-    int32_t mAwaitingExtSeqNo;
-    bool mRequestedRetransmission;
-
-    int32_t mActivePacketType;
-    sp<Assembler> mActiveAssembler;
-
-    int64_t mNextReportTimeUs;
-
-    int32_t mNumDeclaredLost;
-    int32_t mNumDeclaredLostPrior;
-
-    int32_t mRetransmitGeneration;
-    int32_t mDeclareLostGeneration;
-    bool mDeclareLostTimerPending;
-
-    void queuePacket(const sp<ABuffer> &packet);
-    void dequeueMore();
-
-    sp<ABuffer> getNextPacket();
-    void resync();
-
-    void postRetransmitTimer(int64_t delayUs);
-    void postDeclareLostTimer(int64_t delayUs);
-    void cancelTimers();
-
-    DISALLOW_EVIL_CONSTRUCTORS(Source);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-RTPReceiver::Source::Source(RTPReceiver *receiver, uint32_t ssrc)
-    : mReceiver(receiver),
-      mSSRC(ssrc),
-      mFirst(true),
-      mMaxSeq(0),
-      mCycles(0),
-      mBaseSeq(0),
-      mReceived(0),
-      mExpectedPrior(0),
-      mReceivedPrior(0),
-      mFirstArrivalTimeUs(-1ll),
-      mFirstRTPTimeUs(-1ll),
-      mAwaitingExtSeqNo(-1),
-      mRequestedRetransmission(false),
-      mActivePacketType(-1),
-      mNextReportTimeUs(-1ll),
-      mNumDeclaredLost(0),
-      mNumDeclaredLostPrior(0),
-      mRetransmitGeneration(0),
-      mDeclareLostGeneration(0),
-      mDeclareLostTimerPending(false) {
-}
-
-RTPReceiver::Source::~Source() {
-}
-
-void RTPReceiver::Source::onMessageReceived(const sp<AMessage> &msg) {
-    switch (msg->what()) {
-        case kWhatRetransmit:
-        {
-            int32_t generation;
-            CHECK(msg->findInt32("generation", &generation));
-
-            if (generation != mRetransmitGeneration) {
-                break;
-            }
-
-            mRequestedRetransmission = true;
-            mReceiver->requestRetransmission(mSSRC, mAwaitingExtSeqNo);
-
-            modifyPacketStatus(
-                    mAwaitingExtSeqNo, STATUS_REQUESTED_RETRANSMISSION);
-            break;
-        }
-
-        case kWhatDeclareLost:
-        {
-            int32_t generation;
-            CHECK(msg->findInt32("generation", &generation));
-
-            if (generation != mDeclareLostGeneration) {
-                break;
-            }
-
-            cancelTimers();
-
-            ALOGV("Lost packet extSeqNo %d %s",
-                  mAwaitingExtSeqNo,
-                  mRequestedRetransmission ? "*" : "");
-
-            mRequestedRetransmission = false;
-            if (mActiveAssembler != NULL) {
-                mActiveAssembler->signalDiscontinuity();
-            }
-
-            modifyPacketStatus(mAwaitingExtSeqNo, STATUS_DECLARED_LOST);
-
-            // resync();
-            ++mAwaitingExtSeqNo;
-            ++mNumDeclaredLost;
-
-            mReceiver->notifyPacketLost();
-
-            dequeueMore();
-            break;
-        }
-
-        default:
-            TRESPASS();
-    }
-}
-
-void RTPReceiver::Source::onPacketReceived(
-        uint16_t seq, const sp<ABuffer> &buffer) {
-    if (mFirst) {
-        buffer->setInt32Data(mCycles | seq);
-        queuePacket(buffer);
-
-        mFirst = false;
-        mBaseSeq = seq;
-        mMaxSeq = seq;
-        ++mReceived;
-        return;
-    }
-
-    uint16_t udelta = seq - mMaxSeq;
-
-    if (udelta < kMaxDropout) {
-        // In order, with permissible gap.
-
-        if (seq < mMaxSeq) {
-            // Sequence number wrapped - count another 64K cycle
-            mCycles += kRTPSeqMod;
-        }
-
-        mMaxSeq = seq;
-
-        ++mReceived;
-    } else if (udelta <= kRTPSeqMod - kMaxMisorder) {
-        // The sequence number made a very large jump
-        return;
-    } else {
-        // Duplicate or reordered packet.
-    }
-
-    buffer->setInt32Data(mCycles | seq);
-    queuePacket(buffer);
-}
-
-void RTPReceiver::Source::queuePacket(const sp<ABuffer> &packet) {
-    int32_t newExtendedSeqNo = packet->int32Data();
-
-    if (mFirstArrivalTimeUs < 0ll) {
-        mFirstArrivalTimeUs = ALooper::GetNowUs();
-
-        uint32_t rtpTime;
-        CHECK(packet->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
-
-        mFirstRTPTimeUs = (rtpTime * 100ll) / 9ll;
-    }
-
-    if (mAwaitingExtSeqNo >= 0 && newExtendedSeqNo < mAwaitingExtSeqNo) {
-        // We're no longer interested in these. They're old.
-        ALOGV("dropping stale extSeqNo %d", newExtendedSeqNo);
-
-        modifyPacketStatus(newExtendedSeqNo, STATUS_ARRIVED_LATE);
-        return;
-    }
-
-    if (mPackets.empty()) {
-        mPackets.push_back(packet);
-        dequeueMore();
-        return;
-    }
-
-    List<sp<ABuffer> >::iterator firstIt = mPackets.begin();
-    List<sp<ABuffer> >::iterator it = --mPackets.end();
-    for (;;) {
-        int32_t extendedSeqNo = (*it)->int32Data();
-
-        if (extendedSeqNo == newExtendedSeqNo) {
-            // Duplicate packet.
-            return;
-        }
-
-        if (extendedSeqNo < newExtendedSeqNo) {
-            // Insert new packet after the one at "it".
-            mPackets.insert(++it, packet);
-            break;
-        }
-
-        if (it == firstIt) {
-            // Insert new packet before the first existing one.
-            mPackets.insert(it, packet);
-            break;
-        }
-
-        --it;
-    }
-
-    dequeueMore();
-}
-
-void RTPReceiver::Source::dequeueMore() {
-    int64_t nowUs = ALooper::GetNowUs();
-    if (mNextReportTimeUs < 0ll || nowUs >= mNextReportTimeUs) {
-        if (mNextReportTimeUs >= 0ll) {
-            uint32_t expected = (mMaxSeq | mCycles) - mBaseSeq + 1;
-
-            uint32_t expectedInterval = expected - mExpectedPrior;
-            mExpectedPrior = expected;
-
-            uint32_t receivedInterval = mReceived - mReceivedPrior;
-            mReceivedPrior = mReceived;
-
-            int64_t lostInterval =
-                (int64_t)expectedInterval - (int64_t)receivedInterval;
-
-            int32_t declaredLostInterval =
-                mNumDeclaredLost - mNumDeclaredLostPrior;
-
-            mNumDeclaredLostPrior = mNumDeclaredLost;
-
-            if (declaredLostInterval > 0) {
-                ALOGI("lost %lld packets (%.2f %%), declared %d lost\n",
-                      lostInterval,
-                      100.0f * lostInterval / expectedInterval,
-                      declaredLostInterval);
-            }
-        }
-
-        mNextReportTimeUs = nowUs + kReportIntervalUs;
-
-#if TRACK_PACKET_LOSS
-        for (size_t i = 0; i < mLostPackets.size(); ++i) {
-            int32_t key = mLostPackets.keyAt(i);
-            uint32_t value = mLostPackets.valueAt(i);
-
-            AString status;
-            if (value & STATUS_REQUESTED_RETRANSMISSION) {
-                status.append("retrans ");
-            }
-            if (value & STATUS_ARRIVED_LATE) {
-                status.append("arrived-late ");
-            }
-            ALOGI("Packet %d declared lost %s", key, status.c_str());
-        }
-#endif
-    }
-
-    sp<ABuffer> packet;
-    while ((packet = getNextPacket()) != NULL) {
-        if (mDeclareLostTimerPending) {
-            cancelTimers();
-        }
-
-        CHECK_GE(mAwaitingExtSeqNo, 0);
-#if TRACK_PACKET_LOSS
-        mLostPackets.removeItem(mAwaitingExtSeqNo);
-#endif
-
-        int32_t packetType;
-        CHECK(packet->meta()->findInt32("PT", &packetType));
-
-        if (packetType != mActivePacketType) {
-            mActiveAssembler = mReceiver->makeAssembler(packetType);
-            mActivePacketType = packetType;
-        }
-
-        if (mActiveAssembler != NULL) {
-            status_t err = mActiveAssembler->processPacket(packet);
-            if (err != OK) {
-                ALOGV("assembler returned error %d", err);
-            }
-        }
-
-        ++mAwaitingExtSeqNo;
-    }
-
-    if (mDeclareLostTimerPending) {
-        return;
-    }
-
-    if (mPackets.empty()) {
-        return;
-    }
-
-    CHECK_GE(mAwaitingExtSeqNo, 0);
-
-    const sp<ABuffer> &firstPacket = *mPackets.begin();
-
-    uint32_t rtpTime;
-    CHECK(firstPacket->meta()->findInt32(
-                "rtp-time", (int32_t *)&rtpTime));
-
-
-    int64_t rtpUs = (rtpTime * 100ll) / 9ll;
-
-    int64_t maxArrivalTimeUs =
-        mFirstArrivalTimeUs + rtpUs - mFirstRTPTimeUs;
-
-    nowUs = ALooper::GetNowUs();
-
-    CHECK_LT(mAwaitingExtSeqNo, firstPacket->int32Data());
-
-    ALOGV("waiting for %d, comparing against %d, %lld us left",
-          mAwaitingExtSeqNo,
-          firstPacket->int32Data(),
-          maxArrivalTimeUs - nowUs);
-
-    postDeclareLostTimer(maxArrivalTimeUs + kPacketLostAfterUs);
-
-    if (kRequestRetransmissionAfterUs > 0ll) {
-        postRetransmitTimer(
-                maxArrivalTimeUs + kRequestRetransmissionAfterUs);
-    }
-}
-
-sp<ABuffer> RTPReceiver::Source::getNextPacket() {
-    if (mPackets.empty()) {
-        return NULL;
-    }
-
-    int32_t extSeqNo = (*mPackets.begin())->int32Data();
-
-    if (mAwaitingExtSeqNo < 0) {
-        mAwaitingExtSeqNo = extSeqNo;
-    } else if (extSeqNo != mAwaitingExtSeqNo) {
-        return NULL;
-    }
-
-    sp<ABuffer> packet = *mPackets.begin();
-    mPackets.erase(mPackets.begin());
-
-    return packet;
-}
-
-void RTPReceiver::Source::resync() {
-    mAwaitingExtSeqNo = -1;
-}
-
-void RTPReceiver::Source::addReportBlock(
-        uint32_t ssrc, const sp<ABuffer> &buf) {
-    uint32_t extMaxSeq = mMaxSeq | mCycles;
-    uint32_t expected = extMaxSeq - mBaseSeq + 1;
-
-    int64_t lost = (int64_t)expected - (int64_t)mReceived;
-    if (lost > 0x7fffff) {
-        lost = 0x7fffff;
-    } else if (lost < -0x800000) {
-        lost = -0x800000;
-    }
-
-    uint32_t expectedInterval = expected - mExpectedPrior;
-    mExpectedPrior = expected;
-
-    uint32_t receivedInterval = mReceived - mReceivedPrior;
-    mReceivedPrior = mReceived;
-
-    int64_t lostInterval = expectedInterval - receivedInterval;
-
-    uint8_t fractionLost;
-    if (expectedInterval == 0 || lostInterval <=0) {
-        fractionLost = 0;
-    } else {
-        fractionLost = (lostInterval << 8) / expectedInterval;
-    }
-
-    uint8_t *ptr = buf->data() + buf->size();
-
-    ptr[0] = ssrc >> 24;
-    ptr[1] = (ssrc >> 16) & 0xff;
-    ptr[2] = (ssrc >> 8) & 0xff;
-    ptr[3] = ssrc & 0xff;
-
-    ptr[4] = fractionLost;
-
-    ptr[5] = (lost >> 16) & 0xff;
-    ptr[6] = (lost >> 8) & 0xff;
-    ptr[7] = lost & 0xff;
-
-    ptr[8] = extMaxSeq >> 24;
-    ptr[9] = (extMaxSeq >> 16) & 0xff;
-    ptr[10] = (extMaxSeq >> 8) & 0xff;
-    ptr[11] = extMaxSeq & 0xff;
-
-    // XXX TODO:
-
-    ptr[12] = 0x00;  // interarrival jitter
-    ptr[13] = 0x00;
-    ptr[14] = 0x00;
-    ptr[15] = 0x00;
-
-    ptr[16] = 0x00;  // last SR
-    ptr[17] = 0x00;
-    ptr[18] = 0x00;
-    ptr[19] = 0x00;
-
-    ptr[20] = 0x00;  // delay since last SR
-    ptr[21] = 0x00;
-    ptr[22] = 0x00;
-    ptr[23] = 0x00;
-
-    buf->setRange(buf->offset(), buf->size() + 24);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-RTPReceiver::RTPReceiver(
-        const sp<ANetworkSession> &netSession,
-        const sp<AMessage> &notify,
-        uint32_t flags)
-    : mNetSession(netSession),
-      mNotify(notify),
-      mFlags(flags),
-      mRTPMode(TRANSPORT_UNDEFINED),
-      mRTCPMode(TRANSPORT_UNDEFINED),
-      mRTPSessionID(0),
-      mRTCPSessionID(0),
-      mRTPConnected(false),
-      mRTCPConnected(false),
-      mRTPClientSessionID(0),
-      mRTCPClientSessionID(0) {
-}
-
-RTPReceiver::~RTPReceiver() {
-    if (mRTCPClientSessionID != 0) {
-        mNetSession->destroySession(mRTCPClientSessionID);
-        mRTCPClientSessionID = 0;
-    }
-
-    if (mRTPClientSessionID != 0) {
-        mNetSession->destroySession(mRTPClientSessionID);
-        mRTPClientSessionID = 0;
-    }
-
-    if (mRTCPSessionID != 0) {
-        mNetSession->destroySession(mRTCPSessionID);
-        mRTCPSessionID = 0;
-    }
-
-    if (mRTPSessionID != 0) {
-        mNetSession->destroySession(mRTPSessionID);
-        mRTPSessionID = 0;
-    }
-}
-
-status_t RTPReceiver::initAsync(
-        TransportMode rtpMode,
-        TransportMode rtcpMode,
-        int32_t *outLocalRTPPort) {
-    if (mRTPMode != TRANSPORT_UNDEFINED
-            || rtpMode == TRANSPORT_UNDEFINED
-            || rtpMode == TRANSPORT_NONE
-            || rtcpMode == TRANSPORT_UNDEFINED) {
-        return INVALID_OPERATION;
-    }
-
-    CHECK_NE(rtpMode, TRANSPORT_TCP_INTERLEAVED);
-    CHECK_NE(rtcpMode, TRANSPORT_TCP_INTERLEAVED);
-
-    sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id());
-
-    sp<AMessage> rtcpNotify;
-    if (rtcpMode != TRANSPORT_NONE) {
-        rtcpNotify = new AMessage(kWhatRTCPNotify, id());
-    }
-
-    CHECK_EQ(mRTPSessionID, 0);
-    CHECK_EQ(mRTCPSessionID, 0);
-
-    int32_t localRTPPort;
-
-    struct in_addr ifaceAddr;
-    ifaceAddr.s_addr = INADDR_ANY;
-
-    for (;;) {
-        localRTPPort = PickRandomRTPPort();
-
-        status_t err;
-        if (rtpMode == TRANSPORT_UDP) {
-            err = mNetSession->createUDPSession(
-                    localRTPPort,
-                    rtpNotify,
-                    &mRTPSessionID);
-        } else {
-            CHECK_EQ(rtpMode, TRANSPORT_TCP);
-            err = mNetSession->createTCPDatagramSession(
-                    ifaceAddr,
-                    localRTPPort,
-                    rtpNotify,
-                    &mRTPSessionID);
-        }
-
-        if (err != OK) {
-            continue;
-        }
-
-        if (rtcpMode == TRANSPORT_NONE) {
-            break;
-        } else if (rtcpMode == TRANSPORT_UDP) {
-            err = mNetSession->createUDPSession(
-                    localRTPPort + 1,
-                    rtcpNotify,
-                    &mRTCPSessionID);
-        } else {
-            CHECK_EQ(rtpMode, TRANSPORT_TCP);
-            err = mNetSession->createTCPDatagramSession(
-                    ifaceAddr,
-                    localRTPPort + 1,
-                    rtcpNotify,
-                    &mRTCPSessionID);
-        }
-
-        if (err == OK) {
-            break;
-        }
-
-        mNetSession->destroySession(mRTPSessionID);
-        mRTPSessionID = 0;
-    }
-
-    mRTPMode = rtpMode;
-    mRTCPMode = rtcpMode;
-    *outLocalRTPPort = localRTPPort;
-
-    return OK;
-}
-
-status_t RTPReceiver::connect(
-        const char *remoteHost, int32_t remoteRTPPort, int32_t remoteRTCPPort) {
-    status_t err;
-
-    if (mRTPMode == TRANSPORT_UDP) {
-        CHECK(!mRTPConnected);
-
-        err = mNetSession->connectUDPSession(
-                mRTPSessionID, remoteHost, remoteRTPPort);
-
-        if (err != OK) {
-            notifyInitDone(err);
-            return err;
-        }
-
-        ALOGI("connectUDPSession RTP successful.");
-
-        mRTPConnected = true;
-    }
-
-    if (mRTCPMode == TRANSPORT_UDP) {
-        CHECK(!mRTCPConnected);
-
-        err = mNetSession->connectUDPSession(
-                mRTCPSessionID, remoteHost, remoteRTCPPort);
-
-        if (err != OK) {
-            notifyInitDone(err);
-            return err;
-        }
-
-        scheduleSendRR();
-
-        ALOGI("connectUDPSession RTCP successful.");
-
-        mRTCPConnected = true;
-    }
-
-    if (mRTPConnected
-            && (mRTCPConnected || mRTCPMode == TRANSPORT_NONE)) {
-        notifyInitDone(OK);
-    }
-
-    return OK;
-}
-
-status_t RTPReceiver::informSender(const sp<AMessage> &params) {
-    if (!mRTCPConnected) {
-        return INVALID_OPERATION;
-    }
-
-    int64_t avgLatencyUs;
-    CHECK(params->findInt64("avgLatencyUs", &avgLatencyUs));
-
-    int64_t maxLatencyUs;
-    CHECK(params->findInt64("maxLatencyUs", &maxLatencyUs));
-
-    sp<ABuffer> buf = new ABuffer(28);
-
-    uint8_t *ptr = buf->data();
-    ptr[0] = 0x80 | 0;
-    ptr[1] = 204;  // APP
-    ptr[2] = 0;
-
-    CHECK((buf->size() % 4) == 0u);
-    ptr[3] = (buf->size() / 4) - 1;
-
-    ptr[4] = kSourceID >> 24;  // SSRC
-    ptr[5] = (kSourceID >> 16) & 0xff;
-    ptr[6] = (kSourceID >> 8) & 0xff;
-    ptr[7] = kSourceID & 0xff;
-    ptr[8] = 'l';
-    ptr[9] = 'a';
-    ptr[10] = 't';
-    ptr[11] = 'e';
-
-    ptr[12] = avgLatencyUs >> 56;
-    ptr[13] = (avgLatencyUs >> 48) & 0xff;
-    ptr[14] = (avgLatencyUs >> 40) & 0xff;
-    ptr[15] = (avgLatencyUs >> 32) & 0xff;
-    ptr[16] = (avgLatencyUs >> 24) & 0xff;
-    ptr[17] = (avgLatencyUs >> 16) & 0xff;
-    ptr[18] = (avgLatencyUs >> 8) & 0xff;
-    ptr[19] = avgLatencyUs & 0xff;
-
-    ptr[20] = maxLatencyUs >> 56;
-    ptr[21] = (maxLatencyUs >> 48) & 0xff;
-    ptr[22] = (maxLatencyUs >> 40) & 0xff;
-    ptr[23] = (maxLatencyUs >> 32) & 0xff;
-    ptr[24] = (maxLatencyUs >> 24) & 0xff;
-    ptr[25] = (maxLatencyUs >> 16) & 0xff;
-    ptr[26] = (maxLatencyUs >> 8) & 0xff;
-    ptr[27] = maxLatencyUs & 0xff;
-
-    mNetSession->sendRequest(mRTCPSessionID, buf->data(), buf->size());
-
-    return OK;
-}
-
-void RTPReceiver::onMessageReceived(const sp<AMessage> &msg) {
-    switch (msg->what()) {
-        case kWhatRTPNotify:
-        case kWhatRTCPNotify:
-            onNetNotify(msg->what() == kWhatRTPNotify, msg);
-            break;
-
-        case kWhatSendRR:
-        {
-            onSendRR();
-            break;
-        }
-
-        default:
-            TRESPASS();
-    }
-}
-
-void RTPReceiver::onNetNotify(bool isRTP, const sp<AMessage> &msg) {
-    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));
-
-            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;
-            } else if (sessionID == mRTPClientSessionID) {
-                mRTPClientSessionID = 0;
-            } else if (sessionID == mRTCPClientSessionID) {
-                mRTCPClientSessionID = 0;
-            }
-
-            if (!mRTPConnected
-                    || (mRTCPMode != TRANSPORT_NONE && !mRTCPConnected)) {
-                notifyInitDone(err);
-                break;
-            }
-
-            notifyError(err);
-            break;
-        }
-
-        case ANetworkSession::kWhatDatagram:
-        {
-            sp<ABuffer> data;
-            CHECK(msg->findBuffer("data", &data));
-
-            if (isRTP) {
-                if (mFlags & FLAG_AUTO_CONNECT) {
-                    AString fromAddr;
-                    CHECK(msg->findString("fromAddr", &fromAddr));
-
-                    int32_t fromPort;
-                    CHECK(msg->findInt32("fromPort", &fromPort));
-
-                    CHECK_EQ((status_t)OK,
-                             connect(
-                                 fromAddr.c_str(), fromPort, fromPort + 1));
-
-                    mFlags &= ~FLAG_AUTO_CONNECT;
-                }
-
-                onRTPData(data);
-            } else {
-                onRTCPData(data);
-            }
-            break;
-        }
-
-        case ANetworkSession::kWhatClientConnected:
-        {
-            int32_t sessionID;
-            CHECK(msg->findInt32("sessionID", &sessionID));
-
-            if (isRTP) {
-                CHECK_EQ(mRTPMode, TRANSPORT_TCP);
-
-                if (mRTPClientSessionID != 0) {
-                    // We only allow a single client connection.
-                    mNetSession->destroySession(sessionID);
-                    sessionID = 0;
-                    break;
-                }
-
-                mRTPClientSessionID = sessionID;
-                mRTPConnected = true;
-            } else {
-                CHECK_EQ(mRTCPMode, TRANSPORT_TCP);
-
-                if (mRTCPClientSessionID != 0) {
-                    // We only allow a single client connection.
-                    mNetSession->destroySession(sessionID);
-                    sessionID = 0;
-                    break;
-                }
-
-                mRTCPClientSessionID = sessionID;
-                mRTCPConnected = true;
-            }
-
-            if (mRTPConnected
-                    && (mRTCPConnected || mRTCPMode == TRANSPORT_NONE)) {
-                notifyInitDone(OK);
-            }
-            break;
-        }
-    }
-}
-
-void RTPReceiver::notifyInitDone(status_t err) {
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatInitDone);
-    notify->setInt32("err", err);
-    notify->post();
-}
-
-void RTPReceiver::notifyError(status_t err) {
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatError);
-    notify->setInt32("err", err);
-    notify->post();
-}
-
-void RTPReceiver::notifyPacketLost() {
-    sp<AMessage> notify = mNotify->dup();
-    notify->setInt32("what", kWhatPacketLost);
-    notify->post();
-}
-
-status_t RTPReceiver::onRTPData(const sp<ABuffer> &buffer) {
-    size_t size = buffer->size();
-    if (size < 12) {
-        // Too short to be a valid RTP header.
-        return ERROR_MALFORMED;
-    }
-
-    const uint8_t *data = buffer->data();
-
-    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;
-    }
-
-    int numCSRCs = data[0] & 0x0f;
-
-    size_t payloadOffset = 12 + 4 * numCSRCs;
-
-    if (size < payloadOffset) {
-        // Not enough data to fit the basic header and all the CSRC entries.
-        return ERROR_MALFORMED;
-    }
-
-    if (data[0] & 0x10) {
-        // Header eXtension present.
-
-        if (size < payloadOffset + 4) {
-            // Not enough data to fit the basic header, all CSRC entries
-            // and the first 4 bytes of the extension header.
-
-            return ERROR_MALFORMED;
-        }
-
-        const uint8_t *extensionData = &data[payloadOffset];
-
-        size_t extensionLength =
-            4 * (extensionData[2] << 8 | extensionData[3]);
-
-        if (size < payloadOffset + 4 + extensionLength) {
-            return ERROR_MALFORMED;
-        }
-
-        payloadOffset += 4 + extensionLength;
-    }
-
-    uint32_t srcId = U32_AT(&data[8]);
-    uint32_t rtpTime = U32_AT(&data[4]);
-    uint16_t seqNo = U16_AT(&data[2]);
-
-    sp<AMessage> meta = buffer->meta();
-    meta->setInt32("ssrc", srcId);
-    meta->setInt32("rtp-time", rtpTime);
-    meta->setInt32("PT", data[1] & 0x7f);
-    meta->setInt32("M", data[1] >> 7);
-
-    buffer->setRange(payloadOffset, size - payloadOffset);
-
-    ssize_t index = mSources.indexOfKey(srcId);
-    sp<Source> source;
-    if (index < 0) {
-        source = new Source(this, srcId);
-        looper()->registerHandler(source);
-
-        mSources.add(srcId, source);
-    } else {
-        source = mSources.valueAt(index);
-    }
-
-    source->onPacketReceived(seqNo, buffer);
-
-    return OK;
-}
-
-status_t RTPReceiver::onRTCPData(const sp<ABuffer> &data) {
-    ALOGI("onRTCPData");
-    return OK;
-}
-
-void RTPReceiver::addSDES(const sp<ABuffer> &buffer) {
-    uint8_t *data = buffer->data() + buffer->size();
-    data[0] = 0x80 | 1;
-    data[1] = 202;  // SDES
-    data[4] = kSourceID >> 24;  // SSRC
-    data[5] = (kSourceID >> 16) & 0xff;
-    data[6] = (kSourceID >> 8) & 0xff;
-    data[7] = kSourceID & 0xff;
-
-    size_t offset = 8;
-
-    data[offset++] = 1;  // CNAME
-
-    AString cname = "stagefright@somewhere";
-    data[offset++] = cname.size();
-
-    memcpy(&data[offset], cname.c_str(), cname.size());
-    offset += cname.size();
-
-    data[offset++] = 6;  // TOOL
-
-    AString tool = "stagefright/1.0";
-    data[offset++] = tool.size();
-
-    memcpy(&data[offset], tool.c_str(), tool.size());
-    offset += tool.size();
-
-    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);
-}
-
-void RTPReceiver::scheduleSendRR() {
-    (new AMessage(kWhatSendRR, id()))->post(5000000ll);
-}
-
-void RTPReceiver::onSendRR() {
-    sp<ABuffer> buf = new ABuffer(kMaxUDPPacketSize);
-    buf->setRange(0, 0);
-
-    uint8_t *ptr = buf->data();
-    ptr[0] = 0x80 | 0;
-    ptr[1] = 201;  // RR
-    ptr[2] = 0;
-    ptr[3] = 1;
-    ptr[4] = kSourceID >> 24;  // SSRC
-    ptr[5] = (kSourceID >> 16) & 0xff;
-    ptr[6] = (kSourceID >> 8) & 0xff;
-    ptr[7] = kSourceID & 0xff;
-
-    buf->setRange(0, 8);
-
-    size_t numReportBlocks = 0;
-    for (size_t i = 0; i < mSources.size(); ++i) {
-        uint32_t ssrc = mSources.keyAt(i);
-        sp<Source> source = mSources.valueAt(i);
-
-        if (numReportBlocks > 31 || buf->size() + 24 > buf->capacity()) {
-            // Cannot fit another report block.
-            break;
-        }
-
-        source->addReportBlock(ssrc, buf);
-        ++numReportBlocks;
-    }
-
-    ptr[0] |= numReportBlocks;  // 5 bit
-
-    size_t sizeInWordsMinus1 = 1 + 6 * numReportBlocks;
-    ptr[2] = sizeInWordsMinus1 >> 8;
-    ptr[3] = sizeInWordsMinus1 & 0xff;
-
-    buf->setRange(0, (sizeInWordsMinus1 + 1) * 4);
-
-    addSDES(buf);
-
-    mNetSession->sendRequest(mRTCPSessionID, buf->data(), buf->size());
-
-    scheduleSendRR();
-}
-
-status_t RTPReceiver::registerPacketType(
-        uint8_t packetType, PacketizationMode mode) {
-    mPacketTypes.add(packetType, mode);
-
-    return OK;
-}
-
-sp<RTPReceiver::Assembler> RTPReceiver::makeAssembler(uint8_t packetType) {
-    ssize_t index = mPacketTypes.indexOfKey(packetType);
-    if (index < 0) {
-        return NULL;
-    }
-
-    PacketizationMode mode = mPacketTypes.valueAt(index);
-
-    switch (mode) {
-        case PACKETIZATION_NONE:
-        case PACKETIZATION_TRANSPORT_STREAM:
-            return new TSAssembler(mNotify);
-
-        case PACKETIZATION_H264:
-            return new H264Assembler(mNotify);
-
-        default:
-            return NULL;
-    }
-}
-
-void RTPReceiver::requestRetransmission(uint32_t senderSSRC, int32_t extSeqNo) {
-    int32_t blp = 0;
-
-    sp<ABuffer> buf = new ABuffer(16);
-    buf->setRange(0, 0);
-
-    uint8_t *ptr = buf->data();
-    ptr[0] = 0x80 | 1;  // generic NACK
-    ptr[1] = 205;  // TSFB
-    ptr[2] = 0;
-    ptr[3] = 3;
-    ptr[8] = (senderSSRC >> 24) & 0xff;
-    ptr[9] = (senderSSRC >> 16) & 0xff;
-    ptr[10] = (senderSSRC >> 8) & 0xff;
-    ptr[11] = (senderSSRC & 0xff);
-    ptr[8] = (kSourceID >> 24) & 0xff;
-    ptr[9] = (kSourceID >> 16) & 0xff;
-    ptr[10] = (kSourceID >> 8) & 0xff;
-    ptr[11] = (kSourceID & 0xff);
-    ptr[12] = (extSeqNo >> 8) & 0xff;
-    ptr[13] = (extSeqNo & 0xff);
-    ptr[14] = (blp >> 8) & 0xff;
-    ptr[15] = (blp & 0xff);
-
-    buf->setRange(0, 16);
-
-     mNetSession->sendRequest(mRTCPSessionID, buf->data(), buf->size());
-}
-
-void RTPReceiver::Source::modifyPacketStatus(int32_t extSeqNo, uint32_t mask) {
-#if TRACK_PACKET_LOSS
-    ssize_t index = mLostPackets.indexOfKey(extSeqNo);
-    if (index < 0) {
-        mLostPackets.add(extSeqNo, mask);
-    } else {
-        mLostPackets.editValueAt(index) |= mask;
-    }
-#endif
-}
-
-void RTPReceiver::Source::postRetransmitTimer(int64_t timeUs) {
-    int64_t delayUs = timeUs - ALooper::GetNowUs();
-    sp<AMessage> msg = new AMessage(kWhatRetransmit, id());
-    msg->setInt32("generation", mRetransmitGeneration);
-    msg->post(delayUs);
-}
-
-void RTPReceiver::Source::postDeclareLostTimer(int64_t timeUs) {
-    CHECK(!mDeclareLostTimerPending);
-    mDeclareLostTimerPending = true;
-
-    int64_t delayUs = timeUs - ALooper::GetNowUs();
-    sp<AMessage> msg = new AMessage(kWhatDeclareLost, id());
-    msg->setInt32("generation", mDeclareLostGeneration);
-    msg->post(delayUs);
-}
-
-void RTPReceiver::Source::cancelTimers() {
-    ++mRetransmitGeneration;
-    ++mDeclareLostGeneration;
-    mDeclareLostTimerPending = false;
-}
-
-}  // namespace android
-
diff --git a/media/libstagefright/wifi-display/rtp/RTPReceiver.h b/media/libstagefright/wifi-display/rtp/RTPReceiver.h
deleted file mode 100644
index 240ab2e..0000000
--- a/media/libstagefright/wifi-display/rtp/RTPReceiver.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright 2013, 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 RTP_RECEIVER_H_
-
-#define RTP_RECEIVER_H_
-
-#include "RTPBase.h"
-
-#include <media/stagefright/foundation/AHandler.h>
-
-namespace android {
-
-struct ABuffer;
-struct ANetworkSession;
-
-// An object of this class facilitates receiving of media data on an RTP
-// channel. The channel is established over a UDP or TCP connection depending
-// on which "TransportMode" was chosen. In addition different RTP packetization
-// schemes are supported such as "Transport Stream Packets over RTP",
-// or "AVC/H.264 encapsulation as specified in RFC 3984 (non-interleaved mode)"
-struct RTPReceiver : public RTPBase, public AHandler {
-    enum {
-        kWhatInitDone,
-        kWhatError,
-        kWhatAccessUnit,
-        kWhatPacketLost,
-    };
-
-    enum Flags {
-        FLAG_AUTO_CONNECT = 1,
-    };
-    RTPReceiver(
-            const sp<ANetworkSession> &netSession,
-            const sp<AMessage> &notify,
-            uint32_t flags = 0);
-
-    status_t registerPacketType(
-            uint8_t packetType, PacketizationMode mode);
-
-    status_t initAsync(
-            TransportMode rtpMode,
-            TransportMode rtcpMode,
-            int32_t *outLocalRTPPort);
-
-    status_t connect(
-            const char *remoteHost,
-            int32_t remoteRTPPort,
-            int32_t remoteRTCPPort);
-
-    status_t informSender(const sp<AMessage> &params);
-
-protected:
-    virtual ~RTPReceiver();
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
-    enum {
-        kWhatRTPNotify,
-        kWhatRTCPNotify,
-        kWhatSendRR,
-    };
-
-    enum {
-        kSourceID                       = 0xdeadbeef,
-        kPacketLostAfterUs              = 100000,
-        kRequestRetransmissionAfterUs   = -1,
-    };
-
-    struct Assembler;
-    struct H264Assembler;
-    struct Source;
-    struct TSAssembler;
-
-    sp<ANetworkSession> mNetSession;
-    sp<AMessage> mNotify;
-    uint32_t mFlags;
-    TransportMode mRTPMode;
-    TransportMode mRTCPMode;
-    int32_t mRTPSessionID;
-    int32_t mRTCPSessionID;
-    bool mRTPConnected;
-    bool mRTCPConnected;
-
-    int32_t mRTPClientSessionID;  // in TRANSPORT_TCP mode.
-    int32_t mRTCPClientSessionID;  // in TRANSPORT_TCP mode.
-
-    KeyedVector<uint8_t, PacketizationMode> mPacketTypes;
-    KeyedVector<uint32_t, sp<Source> > mSources;
-
-    void onNetNotify(bool isRTP, const sp<AMessage> &msg);
-    status_t onRTPData(const sp<ABuffer> &data);
-    status_t onRTCPData(const sp<ABuffer> &data);
-    void onSendRR();
-
-    void scheduleSendRR();
-    void addSDES(const sp<ABuffer> &buffer);
-
-    void notifyInitDone(status_t err);
-    void notifyError(status_t err);
-    void notifyPacketLost();
-
-    sp<Assembler> makeAssembler(uint8_t packetType);
-
-    void requestRetransmission(uint32_t senderSSRC, int32_t extSeqNo);
-
-    DISALLOW_EVIL_CONSTRUCTORS(RTPReceiver);
-};
-
-}  // namespace android
-
-#endif  // RTP_RECEIVER_H_
diff --git a/media/libstagefright/wifi-display/rtptest.cpp b/media/libstagefright/wifi-display/rtptest.cpp
deleted file mode 100644
index b902f29..0000000
--- a/media/libstagefright/wifi-display/rtptest.cpp
+++ /dev/null
@@ -1,565 +0,0 @@
-/*
- * Copyright 2013, 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_NEBUG 0
-#define LOG_TAG "rtptest"
-#include <utils/Log.h>
-
-#include "rtp/RTPSender.h"
-#include "rtp/RTPReceiver.h"
-#include "TimeSyncer.h"
-
-#include <binder/ProcessState.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AHandler.h>
-#include <media/stagefright/foundation/ALooper.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/ANetworkSession.h>
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/DataSource.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/NuMediaExtractor.h>
-#include <media/stagefright/Utils.h>
-
-#define MEDIA_FILENAME "/sdcard/Frame Counter HD 30FPS_1080p.mp4"
-
-namespace android {
-
-struct PacketSource : public RefBase {
-    PacketSource() {}
-
-    virtual sp<ABuffer> getNextAccessUnit() = 0;
-
-protected:
-    virtual ~PacketSource() {}
-
-private:
-    DISALLOW_EVIL_CONSTRUCTORS(PacketSource);
-};
-
-struct MediaPacketSource : public PacketSource {
-    MediaPacketSource()
-        : mMaxSampleSize(1024 * 1024) {
-        mExtractor = new NuMediaExtractor;
-        CHECK_EQ((status_t)OK,
-                 mExtractor->setDataSource(MEDIA_FILENAME));
-
-        bool haveVideo = false;
-        for (size_t i = 0; i < mExtractor->countTracks(); ++i) {
-            sp<AMessage> format;
-            CHECK_EQ((status_t)OK, mExtractor->getTrackFormat(i, &format));
-
-            AString mime;
-            CHECK(format->findString("mime", &mime));
-
-            if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str())) {
-                mExtractor->selectTrack(i);
-                haveVideo = true;
-                break;
-            }
-        }
-
-        CHECK(haveVideo);
-    }
-
-    virtual sp<ABuffer> getNextAccessUnit() {
-        int64_t timeUs;
-        status_t err = mExtractor->getSampleTime(&timeUs);
-
-        if (err != OK) {
-            return NULL;
-        }
-
-        sp<ABuffer> accessUnit = new ABuffer(mMaxSampleSize);
-        CHECK_EQ((status_t)OK, mExtractor->readSampleData(accessUnit));
-
-        accessUnit->meta()->setInt64("timeUs", timeUs);
-
-        CHECK_EQ((status_t)OK, mExtractor->advance());
-
-        return accessUnit;
-    }
-
-protected:
-    virtual ~MediaPacketSource() {
-    }
-
-private:
-    sp<NuMediaExtractor> mExtractor;
-    size_t mMaxSampleSize;
-
-    DISALLOW_EVIL_CONSTRUCTORS(MediaPacketSource);
-};
-
-struct SimplePacketSource : public PacketSource {
-    SimplePacketSource()
-        : mCounter(0) {
-    }
-
-    virtual sp<ABuffer> getNextAccessUnit() {
-        sp<ABuffer> buffer = new ABuffer(4);
-        uint8_t *dst = buffer->data();
-        dst[0] = mCounter >> 24;
-        dst[1] = (mCounter >> 16) & 0xff;
-        dst[2] = (mCounter >> 8) & 0xff;
-        dst[3] = mCounter & 0xff;
-
-        buffer->meta()->setInt64("timeUs", mCounter * 1000000ll / kFrameRate);
-
-        ++mCounter;
-
-        return buffer;
-    }
-
-protected:
-    virtual ~SimplePacketSource() {
-    }
-
-private:
-    enum {
-        kFrameRate = 30
-    };
-
-    uint32_t mCounter;
-
-    DISALLOW_EVIL_CONSTRUCTORS(SimplePacketSource);
-};
-
-struct TestHandler : public AHandler {
-    TestHandler(const sp<ANetworkSession> &netSession);
-
-    void listen();
-    void connect(const char *host, int32_t port);
-
-protected:
-    virtual ~TestHandler();
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
-    enum {
-        kWhatListen,
-        kWhatConnect,
-        kWhatReceiverNotify,
-        kWhatSenderNotify,
-        kWhatSendMore,
-        kWhatStop,
-        kWhatTimeSyncerNotify,
-    };
-
-#if 1
-    static const RTPBase::TransportMode kRTPMode = RTPBase::TRANSPORT_UDP;
-    static const RTPBase::TransportMode kRTCPMode = RTPBase::TRANSPORT_UDP;
-#else
-    static const RTPBase::TransportMode kRTPMode = RTPBase::TRANSPORT_TCP;
-    static const RTPBase::TransportMode kRTCPMode = RTPBase::TRANSPORT_NONE;
-#endif
-
-#if 1
-    static const RTPBase::PacketizationMode kPacketizationMode
-        = RTPBase::PACKETIZATION_H264;
-#else
-    static const RTPBase::PacketizationMode kPacketizationMode
-        = RTPBase::PACKETIZATION_NONE;
-#endif
-
-    sp<ANetworkSession> mNetSession;
-    sp<PacketSource> mSource;
-    sp<RTPSender> mSender;
-    sp<RTPReceiver> mReceiver;
-
-    sp<TimeSyncer> mTimeSyncer;
-    bool mTimeSyncerStarted;
-
-    int64_t mFirstTimeRealUs;
-    int64_t mFirstTimeMediaUs;
-
-    int64_t mTimeOffsetUs;
-    bool mTimeOffsetValid;
-
-    status_t readMore();
-
-    DISALLOW_EVIL_CONSTRUCTORS(TestHandler);
-};
-
-TestHandler::TestHandler(const sp<ANetworkSession> &netSession)
-    : mNetSession(netSession),
-      mTimeSyncerStarted(false),
-      mFirstTimeRealUs(-1ll),
-      mFirstTimeMediaUs(-1ll),
-      mTimeOffsetUs(-1ll),
-      mTimeOffsetValid(false) {
-}
-
-TestHandler::~TestHandler() {
-}
-
-void TestHandler::listen() {
-    sp<AMessage> msg = new AMessage(kWhatListen, id());
-    msg->post();
-}
-
-void TestHandler::connect(const char *host, int32_t port) {
-    sp<AMessage> msg = new AMessage(kWhatConnect, id());
-    msg->setString("host", host);
-    msg->setInt32("port", port);
-    msg->post();
-}
-
-static void dumpDelay(int64_t delayMs) {
-    static const int64_t kMinDelayMs = 0;
-    static const int64_t kMaxDelayMs = 300;
-
-    const char *kPattern = "########################################";
-    size_t kPatternSize = strlen(kPattern);
-
-    int n = (kPatternSize * (delayMs - kMinDelayMs))
-                / (kMaxDelayMs - kMinDelayMs);
-
-    if (n < 0) {
-        n = 0;
-    } else if ((size_t)n > kPatternSize) {
-        n = kPatternSize;
-    }
-
-    ALOGI("(%4lld ms) %s\n",
-          delayMs,
-          kPattern + kPatternSize - n);
-}
-
-void TestHandler::onMessageReceived(const sp<AMessage> &msg) {
-    switch (msg->what()) {
-        case kWhatListen:
-        {
-            sp<AMessage> notify = new AMessage(kWhatTimeSyncerNotify, id());
-            mTimeSyncer = new TimeSyncer(mNetSession, notify);
-            looper()->registerHandler(mTimeSyncer);
-
-            notify = new AMessage(kWhatReceiverNotify, id());
-            mReceiver = new RTPReceiver(
-                    mNetSession, notify, RTPReceiver::FLAG_AUTO_CONNECT);
-            looper()->registerHandler(mReceiver);
-
-            CHECK_EQ((status_t)OK,
-                     mReceiver->registerPacketType(33, kPacketizationMode));
-
-            int32_t receiverRTPPort;
-            CHECK_EQ((status_t)OK,
-                     mReceiver->initAsync(
-                         kRTPMode,
-                         kRTCPMode,
-                         &receiverRTPPort));
-
-            printf("picked receiverRTPPort %d\n", receiverRTPPort);
-
-#if 0
-            CHECK_EQ((status_t)OK,
-                     mReceiver->connect(
-                         "127.0.0.1", senderRTPPort, senderRTPPort + 1));
-#endif
-            break;
-        }
-
-        case kWhatConnect:
-        {
-            AString host;
-            CHECK(msg->findString("host", &host));
-
-            sp<AMessage> notify = new AMessage(kWhatTimeSyncerNotify, id());
-            mTimeSyncer = new TimeSyncer(mNetSession, notify);
-            looper()->registerHandler(mTimeSyncer);
-            mTimeSyncer->startServer(8123);
-
-            int32_t receiverRTPPort;
-            CHECK(msg->findInt32("port", &receiverRTPPort));
-
-#if 1
-            mSource = new MediaPacketSource;
-#else
-            mSource = new SimplePacketSource;
-#endif
-
-            notify = new AMessage(kWhatSenderNotify, id());
-            mSender = new RTPSender(mNetSession, notify);
-
-            looper()->registerHandler(mSender);
-
-            int32_t senderRTPPort;
-            CHECK_EQ((status_t)OK,
-                     mSender->initAsync(
-                         host.c_str(),
-                         receiverRTPPort,
-                         kRTPMode,
-                         kRTCPMode == RTPBase::TRANSPORT_NONE
-                            ? -1 : receiverRTPPort + 1,
-                         kRTCPMode,
-                         &senderRTPPort));
-
-            printf("picked senderRTPPort %d\n", senderRTPPort);
-            break;
-        }
-
-        case kWhatSenderNotify:
-        {
-            ALOGI("kWhatSenderNotify");
-
-            int32_t what;
-            CHECK(msg->findInt32("what", &what));
-
-            switch (what) {
-                case RTPSender::kWhatInitDone:
-                {
-                    int32_t err;
-                    CHECK(msg->findInt32("err", &err));
-
-                    ALOGI("RTPSender::initAsync completed w/ err %d", err);
-
-                    if (err == OK) {
-                        err = readMore();
-
-                        if (err != OK) {
-                            (new AMessage(kWhatStop, id()))->post();
-                        }
-                    }
-                    break;
-                }
-
-                case RTPSender::kWhatError:
-                    break;
-            }
-            break;
-        }
-
-        case kWhatReceiverNotify:
-        {
-            ALOGV("kWhatReceiverNotify");
-
-            int32_t what;
-            CHECK(msg->findInt32("what", &what));
-
-            switch (what) {
-                case RTPReceiver::kWhatInitDone:
-                {
-                    int32_t err;
-                    CHECK(msg->findInt32("err", &err));
-
-                    ALOGI("RTPReceiver::initAsync completed w/ err %d", err);
-                    break;
-                }
-
-                case RTPReceiver::kWhatError:
-                    break;
-
-                case RTPReceiver::kWhatAccessUnit:
-                {
-#if 0
-                    if (!mTimeSyncerStarted) {
-                        mTimeSyncer->startClient("172.18.41.216", 8123);
-                        mTimeSyncerStarted = true;
-                    }
-
-                    sp<ABuffer> accessUnit;
-                    CHECK(msg->findBuffer("accessUnit", &accessUnit));
-
-                    int64_t timeUs;
-                    CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
-
-                    if (mTimeOffsetValid) {
-                        timeUs -= mTimeOffsetUs;
-                        int64_t nowUs = ALooper::GetNowUs();
-                        int64_t delayMs = (nowUs - timeUs) / 1000ll;
-
-                        dumpDelay(delayMs);
-                    }
-#endif
-                    break;
-                }
-
-                case RTPReceiver::kWhatPacketLost:
-                    ALOGV("kWhatPacketLost");
-                    break;
-
-                default:
-                    TRESPASS();
-            }
-            break;
-        }
-
-        case kWhatSendMore:
-        {
-            sp<ABuffer> accessUnit;
-            CHECK(msg->findBuffer("accessUnit", &accessUnit));
-
-            CHECK_EQ((status_t)OK,
-                     mSender->queueBuffer(
-                         accessUnit,
-                         33,
-                         kPacketizationMode));
-
-            status_t err = readMore();
-
-            if (err != OK) {
-                (new AMessage(kWhatStop, id()))->post();
-            }
-            break;
-        }
-
-        case kWhatStop:
-        {
-            if (mReceiver != NULL) {
-                looper()->unregisterHandler(mReceiver->id());
-                mReceiver.clear();
-            }
-
-            if (mSender != NULL) {
-                looper()->unregisterHandler(mSender->id());
-                mSender.clear();
-            }
-
-            mSource.clear();
-
-            looper()->stop();
-            break;
-        }
-
-        case kWhatTimeSyncerNotify:
-        {
-            CHECK(msg->findInt64("offset", &mTimeOffsetUs));
-            mTimeOffsetValid = true;
-            break;
-        }
-
-        default:
-            TRESPASS();
-    }
-}
-
-status_t TestHandler::readMore() {
-    sp<ABuffer> accessUnit = mSource->getNextAccessUnit();
-
-    if (accessUnit == NULL) {
-        return ERROR_END_OF_STREAM;
-    }
-
-    int64_t timeUs;
-    CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
-
-    int64_t nowUs = ALooper::GetNowUs();
-    int64_t whenUs;
-
-    if (mFirstTimeRealUs < 0ll) {
-        mFirstTimeRealUs = whenUs = nowUs;
-        mFirstTimeMediaUs = timeUs;
-    } else {
-        whenUs = mFirstTimeRealUs + timeUs - mFirstTimeMediaUs;
-    }
-
-    accessUnit->meta()->setInt64("timeUs", whenUs);
-
-    sp<AMessage> msg = new AMessage(kWhatSendMore, id());
-    msg->setBuffer("accessUnit", accessUnit);
-    msg->post(whenUs - nowUs);
-
-    return OK;
-}
-
-}  // namespace android
-
-static void usage(const char *me) {
-    fprintf(stderr,
-            "usage: %s -c host:port\tconnect to remote host\n"
-            "               -l       \tlisten\n",
-            me);
-}
-
-int main(int argc, char **argv) {
-    using namespace android;
-
-    // srand(time(NULL));
-
-    ProcessState::self()->startThreadPool();
-
-    DataSource::RegisterDefaultSniffers();
-
-    bool listen = false;
-    int32_t connectToPort = -1;
-    AString connectToHost;
-
-    int res;
-    while ((res = getopt(argc, argv, "hc:l")) >= 0) {
-        switch (res) {
-            case 'c':
-            {
-                const char *colonPos = strrchr(optarg, ':');
-
-                if (colonPos == NULL) {
-                    usage(argv[0]);
-                    exit(1);
-                }
-
-                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 'l':
-            {
-                listen = true;
-                break;
-            }
-
-            case '?':
-            case 'h':
-                usage(argv[0]);
-                exit(1);
-        }
-    }
-
-    if (!listen && connectToPort < 0) {
-        fprintf(stderr,
-                "You need to select either client or server mode.\n");
-        exit(1);
-    }
-
-    sp<ANetworkSession> netSession = new ANetworkSession;
-    netSession->start();
-
-    sp<ALooper> looper = new ALooper;
-
-    sp<TestHandler> handler = new TestHandler(netSession);
-    looper->registerHandler(handler);
-
-    if (listen) {
-        handler->listen();
-    }
-
-    if (connectToPort >= 0) {
-        handler->connect(connectToHost.c_str(), connectToPort);
-    }
-
-    looper->start(true /* runOnCallingThread */);
-
-    return 0;
-}
-
diff --git a/media/libstagefright/wifi-display/sink/DirectRenderer.cpp b/media/libstagefright/wifi-display/sink/DirectRenderer.cpp
deleted file mode 100644
index cdb2267..0000000
--- a/media/libstagefright/wifi-display/sink/DirectRenderer.cpp
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
- * 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 "DirectRenderer"
-#include <utils/Log.h>
-
-#include "DirectRenderer.h"
-
-#include <gui/SurfaceComposerClient.h>
-#include <gui/Surface.h>
-#include <media/AudioTrack.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/foundation/hexdump.h>
-#include <media/stagefright/MediaCodec.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaErrors.h>
-
-namespace android {
-
-/*
-   Drives the decoding process using a MediaCodec instance. Input buffers
-   queued by calls to "queueInputBuffer" are fed to the decoder as soon
-   as the decoder is ready for them, the client is notified about output
-   buffers as the decoder spits them out.
-*/
-struct DirectRenderer::DecoderContext : public AHandler {
-    enum {
-        kWhatOutputBufferReady,
-    };
-    DecoderContext(const sp<AMessage> &notify);
-
-    status_t init(
-            const sp<AMessage> &format,
-            const sp<IGraphicBufferProducer> &surfaceTex);
-
-    void queueInputBuffer(const sp<ABuffer> &accessUnit);
-
-    status_t renderOutputBufferAndRelease(size_t index);
-    status_t releaseOutputBuffer(size_t index);
-
-protected:
-    virtual ~DecoderContext();
-
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
-    enum {
-        kWhatDecoderNotify,
-    };
-
-    sp<AMessage> mNotify;
-    sp<ALooper> mDecoderLooper;
-    sp<MediaCodec> mDecoder;
-    Vector<sp<ABuffer> > mDecoderInputBuffers;
-    Vector<sp<ABuffer> > mDecoderOutputBuffers;
-    List<size_t> mDecoderInputBuffersAvailable;
-    bool mDecoderNotificationPending;
-
-    List<sp<ABuffer> > mAccessUnits;
-
-    void onDecoderNotify();
-    void scheduleDecoderNotification();
-    void queueDecoderInputBuffers();
-
-    void queueOutputBuffer(
-            size_t index, int64_t timeUs, const sp<ABuffer> &buffer);
-
-    DISALLOW_EVIL_CONSTRUCTORS(DecoderContext);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-/*
-   A "push" audio renderer. The primary function of this renderer is to use
-   an AudioTrack in push mode and making sure not to block the event loop
-   be ensuring that calls to AudioTrack::write never block. This is done by
-   estimating an upper bound of data that can be written to the AudioTrack
-   buffer without delay.
-*/
-struct DirectRenderer::AudioRenderer : public AHandler {
-    AudioRenderer(const sp<DecoderContext> &decoderContext);
-
-    void queueInputBuffer(
-            size_t index, int64_t timeUs, const sp<ABuffer> &buffer);
-
-protected:
-    virtual ~AudioRenderer();
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
-    enum {
-        kWhatPushAudio,
-    };
-
-    struct BufferInfo {
-        size_t mIndex;
-        int64_t mTimeUs;
-        sp<ABuffer> mBuffer;
-    };
-
-    sp<DecoderContext> mDecoderContext;
-    sp<AudioTrack> mAudioTrack;
-
-    List<BufferInfo> mInputBuffers;
-    bool mPushPending;
-
-    size_t mNumFramesWritten;
-
-    void schedulePushIfNecessary();
-    void onPushAudio();
-
-    ssize_t writeNonBlocking(const uint8_t *data, size_t size);
-
-    DISALLOW_EVIL_CONSTRUCTORS(AudioRenderer);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-DirectRenderer::DecoderContext::DecoderContext(const sp<AMessage> &notify)
-    : mNotify(notify),
-      mDecoderNotificationPending(false) {
-}
-
-DirectRenderer::DecoderContext::~DecoderContext() {
-    if (mDecoder != NULL) {
-        mDecoder->release();
-        mDecoder.clear();
-
-        mDecoderLooper->stop();
-        mDecoderLooper.clear();
-    }
-}
-
-status_t DirectRenderer::DecoderContext::init(
-        const sp<AMessage> &format,
-        const sp<IGraphicBufferProducer> &surfaceTex) {
-    CHECK(mDecoder == NULL);
-
-    AString mime;
-    CHECK(format->findString("mime", &mime));
-
-    mDecoderLooper = new ALooper;
-    mDecoderLooper->setName("video codec looper");
-
-    mDecoderLooper->start(
-            false /* runOnCallingThread */,
-            false /* canCallJava */,
-            PRIORITY_DEFAULT);
-
-    mDecoder = MediaCodec::CreateByType(
-            mDecoderLooper, mime.c_str(), false /* encoder */);
-
-    CHECK(mDecoder != NULL);
-
-    status_t err = mDecoder->configure(
-            format,
-            surfaceTex == NULL
-                ? NULL : new Surface(surfaceTex),
-            NULL /* crypto */,
-            0 /* flags */);
-    CHECK_EQ(err, (status_t)OK);
-
-    err = mDecoder->start();
-    CHECK_EQ(err, (status_t)OK);
-
-    err = mDecoder->getInputBuffers(
-            &mDecoderInputBuffers);
-    CHECK_EQ(err, (status_t)OK);
-
-    err = mDecoder->getOutputBuffers(
-            &mDecoderOutputBuffers);
-    CHECK_EQ(err, (status_t)OK);
-
-    scheduleDecoderNotification();
-
-    return OK;
-}
-
-void DirectRenderer::DecoderContext::queueInputBuffer(
-        const sp<ABuffer> &accessUnit) {
-    CHECK(mDecoder != NULL);
-
-    mAccessUnits.push_back(accessUnit);
-    queueDecoderInputBuffers();
-}
-
-status_t DirectRenderer::DecoderContext::renderOutputBufferAndRelease(
-        size_t index) {
-    return mDecoder->renderOutputBufferAndRelease(index);
-}
-
-status_t DirectRenderer::DecoderContext::releaseOutputBuffer(size_t index) {
-    return mDecoder->releaseOutputBuffer(index);
-}
-
-void DirectRenderer::DecoderContext::queueDecoderInputBuffers() {
-    if (mDecoder == NULL) {
-        return;
-    }
-
-    bool submittedMore = false;
-
-    while (!mAccessUnits.empty()
-            && !mDecoderInputBuffersAvailable.empty()) {
-        size_t index = *mDecoderInputBuffersAvailable.begin();
-
-        mDecoderInputBuffersAvailable.erase(
-                mDecoderInputBuffersAvailable.begin());
-
-        sp<ABuffer> srcBuffer = *mAccessUnits.begin();
-        mAccessUnits.erase(mAccessUnits.begin());
-
-        const sp<ABuffer> &dstBuffer =
-            mDecoderInputBuffers.itemAt(index);
-
-        memcpy(dstBuffer->data(), srcBuffer->data(), srcBuffer->size());
-
-        int64_t timeUs;
-        CHECK(srcBuffer->meta()->findInt64("timeUs", &timeUs));
-
-        status_t err = mDecoder->queueInputBuffer(
-                index,
-                0 /* offset */,
-                srcBuffer->size(),
-                timeUs,
-                0 /* flags */);
-        CHECK_EQ(err, (status_t)OK);
-
-        submittedMore = true;
-    }
-
-    if (submittedMore) {
-        scheduleDecoderNotification();
-    }
-}
-
-void DirectRenderer::DecoderContext::onMessageReceived(
-        const sp<AMessage> &msg) {
-    switch (msg->what()) {
-        case kWhatDecoderNotify:
-        {
-            onDecoderNotify();
-            break;
-        }
-
-        default:
-            TRESPASS();
-    }
-}
-
-void DirectRenderer::DecoderContext::onDecoderNotify() {
-    mDecoderNotificationPending = false;
-
-    for (;;) {
-        size_t index;
-        status_t err = mDecoder->dequeueInputBuffer(&index);
-
-        if (err == OK) {
-            mDecoderInputBuffersAvailable.push_back(index);
-        } else if (err == -EAGAIN) {
-            break;
-        } else {
-            TRESPASS();
-        }
-    }
-
-    queueDecoderInputBuffers();
-
-    for (;;) {
-        size_t index;
-        size_t offset;
-        size_t size;
-        int64_t timeUs;
-        uint32_t flags;
-        status_t err = mDecoder->dequeueOutputBuffer(
-                &index,
-                &offset,
-                &size,
-                &timeUs,
-                &flags);
-
-        if (err == OK) {
-            queueOutputBuffer(
-                    index, timeUs, mDecoderOutputBuffers.itemAt(index));
-        } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) {
-            err = mDecoder->getOutputBuffers(
-                    &mDecoderOutputBuffers);
-            CHECK_EQ(err, (status_t)OK);
-        } else if (err == INFO_FORMAT_CHANGED) {
-            // We don't care.
-        } else if (err == -EAGAIN) {
-            break;
-        } else {
-            TRESPASS();
-        }
-    }
-
-    scheduleDecoderNotification();
-}
-
-void DirectRenderer::DecoderContext::scheduleDecoderNotification() {
-    if (mDecoderNotificationPending) {
-        return;
-    }
-
-    sp<AMessage> notify =
-        new AMessage(kWhatDecoderNotify, id());
-
-    mDecoder->requestActivityNotification(notify);
-    mDecoderNotificationPending = true;
-}
-
-void DirectRenderer::DecoderContext::queueOutputBuffer(
-        size_t index, int64_t timeUs, const sp<ABuffer> &buffer) {
-    sp<AMessage> msg = mNotify->dup();
-    msg->setInt32("what", kWhatOutputBufferReady);
-    msg->setSize("index", index);
-    msg->setInt64("timeUs", timeUs);
-    msg->setBuffer("buffer", buffer);
-    msg->post();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-DirectRenderer::AudioRenderer::AudioRenderer(
-        const sp<DecoderContext> &decoderContext)
-    : mDecoderContext(decoderContext),
-      mPushPending(false),
-      mNumFramesWritten(0) {
-    mAudioTrack = new AudioTrack(
-            AUDIO_STREAM_DEFAULT,
-            48000.0f,
-            AUDIO_FORMAT_PCM,
-            AUDIO_CHANNEL_OUT_STEREO,
-            (int)0 /* frameCount */);
-
-    CHECK_EQ((status_t)OK, mAudioTrack->initCheck());
-
-    mAudioTrack->start();
-}
-
-DirectRenderer::AudioRenderer::~AudioRenderer() {
-}
-
-void DirectRenderer::AudioRenderer::queueInputBuffer(
-        size_t index, int64_t timeUs, const sp<ABuffer> &buffer) {
-    BufferInfo info;
-    info.mIndex = index;
-    info.mTimeUs = timeUs;
-    info.mBuffer = buffer;
-
-    mInputBuffers.push_back(info);
-    schedulePushIfNecessary();
-}
-
-void DirectRenderer::AudioRenderer::onMessageReceived(
-        const sp<AMessage> &msg) {
-    switch (msg->what()) {
-        case kWhatPushAudio:
-        {
-            onPushAudio();
-            break;
-        }
-
-        default:
-            break;
-    }
-}
-
-void DirectRenderer::AudioRenderer::schedulePushIfNecessary() {
-    if (mPushPending || mInputBuffers.empty()) {
-        return;
-    }
-
-    mPushPending = true;
-
-    uint32_t numFramesPlayed;
-    CHECK_EQ(mAudioTrack->getPosition(&numFramesPlayed),
-             (status_t)OK);
-
-    uint32_t numFramesPendingPlayout = mNumFramesWritten - numFramesPlayed;
-
-    // This is how long the audio sink will have data to
-    // play back.
-    const float msecsPerFrame = 1000.0f / mAudioTrack->getSampleRate();
-
-    int64_t delayUs =
-        msecsPerFrame * numFramesPendingPlayout * 1000ll;
-
-    // Let's give it more data after about half that time
-    // has elapsed.
-    (new AMessage(kWhatPushAudio, id()))->post(delayUs / 2);
-}
-
-void DirectRenderer::AudioRenderer::onPushAudio() {
-    mPushPending = false;
-
-    while (!mInputBuffers.empty()) {
-        const BufferInfo &info = *mInputBuffers.begin();
-
-        ssize_t n = writeNonBlocking(
-                info.mBuffer->data(), info.mBuffer->size());
-
-        if (n < (ssize_t)info.mBuffer->size()) {
-            CHECK_GE(n, 0);
-
-            info.mBuffer->setRange(
-                    info.mBuffer->offset() + n, info.mBuffer->size() - n);
-            break;
-        }
-
-        mDecoderContext->releaseOutputBuffer(info.mIndex);
-
-        mInputBuffers.erase(mInputBuffers.begin());
-    }
-
-    schedulePushIfNecessary();
-}
-
-ssize_t DirectRenderer::AudioRenderer::writeNonBlocking(
-        const uint8_t *data, size_t size) {
-    uint32_t numFramesPlayed;
-    status_t err = mAudioTrack->getPosition(&numFramesPlayed);
-    if (err != OK) {
-        return err;
-    }
-
-    ssize_t numFramesAvailableToWrite =
-        mAudioTrack->frameCount() - (mNumFramesWritten - numFramesPlayed);
-
-    size_t numBytesAvailableToWrite =
-        numFramesAvailableToWrite * mAudioTrack->frameSize();
-
-    if (size > numBytesAvailableToWrite) {
-        size = numBytesAvailableToWrite;
-    }
-
-    CHECK_EQ(mAudioTrack->write(data, size), (ssize_t)size);
-
-    size_t numFramesWritten = size / mAudioTrack->frameSize();
-    mNumFramesWritten += numFramesWritten;
-
-    return size;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-DirectRenderer::DirectRenderer(
-        const sp<IGraphicBufferProducer> &bufferProducer)
-    : mSurfaceTex(bufferProducer),
-      mVideoRenderPending(false),
-      mNumFramesLate(0),
-      mNumFrames(0) {
-}
-
-DirectRenderer::~DirectRenderer() {
-}
-
-void DirectRenderer::onMessageReceived(const sp<AMessage> &msg) {
-    switch (msg->what()) {
-        case kWhatDecoderNotify:
-        {
-            onDecoderNotify(msg);
-            break;
-        }
-
-        case kWhatRenderVideo:
-        {
-            onRenderVideo();
-            break;
-        }
-
-        case kWhatQueueAccessUnit:
-            onQueueAccessUnit(msg);
-            break;
-
-        case kWhatSetFormat:
-            onSetFormat(msg);
-            break;
-
-        default:
-            TRESPASS();
-    }
-}
-
-void DirectRenderer::setFormat(size_t trackIndex, const sp<AMessage> &format) {
-    sp<AMessage> msg = new AMessage(kWhatSetFormat, id());
-    msg->setSize("trackIndex", trackIndex);
-    msg->setMessage("format", format);
-    msg->post();
-}
-
-void DirectRenderer::onSetFormat(const sp<AMessage> &msg) {
-    size_t trackIndex;
-    CHECK(msg->findSize("trackIndex", &trackIndex));
-
-    sp<AMessage> format;
-    CHECK(msg->findMessage("format", &format));
-
-    internalSetFormat(trackIndex, format);
-}
-
-void DirectRenderer::internalSetFormat(
-        size_t trackIndex, const sp<AMessage> &format) {
-    CHECK_LT(trackIndex, 2u);
-
-    CHECK(mDecoderContext[trackIndex] == NULL);
-
-    sp<AMessage> notify = new AMessage(kWhatDecoderNotify, id());
-    notify->setSize("trackIndex", trackIndex);
-
-    mDecoderContext[trackIndex] = new DecoderContext(notify);
-    looper()->registerHandler(mDecoderContext[trackIndex]);
-
-    CHECK_EQ((status_t)OK,
-             mDecoderContext[trackIndex]->init(
-                 format, trackIndex == 0 ? mSurfaceTex : NULL));
-
-    if (trackIndex == 1) {
-        // Audio
-        mAudioRenderer = new AudioRenderer(mDecoderContext[1]);
-        looper()->registerHandler(mAudioRenderer);
-    }
-}
-
-void DirectRenderer::queueAccessUnit(
-        size_t trackIndex, const sp<ABuffer> &accessUnit) {
-    sp<AMessage> msg = new AMessage(kWhatQueueAccessUnit, id());
-    msg->setSize("trackIndex", trackIndex);
-    msg->setBuffer("accessUnit", accessUnit);
-    msg->post();
-}
-
-void DirectRenderer::onQueueAccessUnit(const sp<AMessage> &msg) {
-    size_t trackIndex;
-    CHECK(msg->findSize("trackIndex", &trackIndex));
-
-    sp<ABuffer> accessUnit;
-    CHECK(msg->findBuffer("accessUnit", &accessUnit));
-
-    CHECK_LT(trackIndex, 2u);
-    CHECK(mDecoderContext[trackIndex] != NULL);
-
-    mDecoderContext[trackIndex]->queueInputBuffer(accessUnit);
-}
-
-void DirectRenderer::onDecoderNotify(const sp<AMessage> &msg) {
-    size_t trackIndex;
-    CHECK(msg->findSize("trackIndex", &trackIndex));
-
-    int32_t what;
-    CHECK(msg->findInt32("what", &what));
-
-    switch (what) {
-        case DecoderContext::kWhatOutputBufferReady:
-        {
-            size_t index;
-            CHECK(msg->findSize("index", &index));
-
-            int64_t timeUs;
-            CHECK(msg->findInt64("timeUs", &timeUs));
-
-            sp<ABuffer> buffer;
-            CHECK(msg->findBuffer("buffer", &buffer));
-
-            queueOutputBuffer(trackIndex, index, timeUs, buffer);
-            break;
-        }
-
-        default:
-            TRESPASS();
-    }
-}
-
-void DirectRenderer::queueOutputBuffer(
-        size_t trackIndex,
-        size_t index, int64_t timeUs, const sp<ABuffer> &buffer) {
-    if (trackIndex == 1) {
-        // Audio
-        mAudioRenderer->queueInputBuffer(index, timeUs, buffer);
-        return;
-    }
-
-    OutputInfo info;
-    info.mIndex = index;
-    info.mTimeUs = timeUs;
-    info.mBuffer = buffer;
-    mVideoOutputBuffers.push_back(info);
-
-    scheduleVideoRenderIfNecessary();
-}
-
-void DirectRenderer::scheduleVideoRenderIfNecessary() {
-    if (mVideoRenderPending || mVideoOutputBuffers.empty()) {
-        return;
-    }
-
-    mVideoRenderPending = true;
-
-    int64_t timeUs = (*mVideoOutputBuffers.begin()).mTimeUs;
-    int64_t nowUs = ALooper::GetNowUs();
-
-    int64_t delayUs = timeUs - nowUs;
-
-    (new AMessage(kWhatRenderVideo, id()))->post(delayUs);
-}
-
-void DirectRenderer::onRenderVideo() {
-    mVideoRenderPending = false;
-
-    int64_t nowUs = ALooper::GetNowUs();
-
-    while (!mVideoOutputBuffers.empty()) {
-        const OutputInfo &info = *mVideoOutputBuffers.begin();
-
-        if (info.mTimeUs > nowUs) {
-            break;
-        }
-
-        if (info.mTimeUs + 15000ll < nowUs) {
-            ++mNumFramesLate;
-        }
-        ++mNumFrames;
-
-        status_t err =
-            mDecoderContext[0]->renderOutputBufferAndRelease(info.mIndex);
-        CHECK_EQ(err, (status_t)OK);
-
-        mVideoOutputBuffers.erase(mVideoOutputBuffers.begin());
-    }
-
-    scheduleVideoRenderIfNecessary();
-}
-
-}  // namespace android
-
diff --git a/media/libstagefright/wifi-display/sink/DirectRenderer.h b/media/libstagefright/wifi-display/sink/DirectRenderer.h
deleted file mode 100644
index 07c2170..0000000
--- a/media/libstagefright/wifi-display/sink/DirectRenderer.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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 DIRECT_RENDERER_H_
-
-#define DIRECT_RENDERER_H_
-
-#include <media/stagefright/foundation/AHandler.h>
-
-namespace android {
-
-struct ABuffer;
-struct IGraphicBufferProducer;
-
-// Renders audio and video data queued by calls to "queueAccessUnit".
-struct DirectRenderer : public AHandler {
-    DirectRenderer(const sp<IGraphicBufferProducer> &bufferProducer);
-
-    void setFormat(size_t trackIndex, const sp<AMessage> &format);
-    void queueAccessUnit(size_t trackIndex, const sp<ABuffer> &accessUnit);
-
-protected:
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-    virtual ~DirectRenderer();
-
-private:
-    struct DecoderContext;
-    struct AudioRenderer;
-
-    enum {
-        kWhatDecoderNotify,
-        kWhatRenderVideo,
-        kWhatQueueAccessUnit,
-        kWhatSetFormat,
-    };
-
-    struct OutputInfo {
-        size_t mIndex;
-        int64_t mTimeUs;
-        sp<ABuffer> mBuffer;
-    };
-
-    sp<IGraphicBufferProducer> mSurfaceTex;
-
-    sp<DecoderContext> mDecoderContext[2];
-    List<OutputInfo> mVideoOutputBuffers;
-
-    bool mVideoRenderPending;
-
-    sp<AudioRenderer> mAudioRenderer;
-
-    int32_t mNumFramesLate;
-    int32_t mNumFrames;
-
-    void onDecoderNotify(const sp<AMessage> &msg);
-
-    void queueOutputBuffer(
-            size_t trackIndex,
-            size_t index, int64_t timeUs, const sp<ABuffer> &buffer);
-
-    void scheduleVideoRenderIfNecessary();
-    void onRenderVideo();
-
-    void onSetFormat(const sp<AMessage> &msg);
-    void onQueueAccessUnit(const sp<AMessage> &msg);
-
-    void internalSetFormat(size_t trackIndex, const sp<AMessage> &format);
-
-    DISALLOW_EVIL_CONSTRUCTORS(DirectRenderer);
-};
-
-}  // namespace android
-
-#endif  // DIRECT_RENDERER_H_
diff --git a/media/libstagefright/wifi-display/sink/WifiDisplaySink.cpp b/media/libstagefright/wifi-display/sink/WifiDisplaySink.cpp
deleted file mode 100644
index bc88f1e..0000000
--- a/media/libstagefright/wifi-display/sink/WifiDisplaySink.cpp
+++ /dev/null
@@ -1,917 +0,0 @@
-/*
- * 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 "WifiDisplaySink"
-#include <utils/Log.h>
-
-#include "WifiDisplaySink.h"
-
-#include "DirectRenderer.h"
-#include "MediaReceiver.h"
-#include "TimeSyncer.h"
-
-#include <cutils/properties.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/ParsedMessage.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/Utils.h>
-
-namespace android {
-
-// static
-const AString WifiDisplaySink::sUserAgent = MakeUserAgent();
-
-WifiDisplaySink::WifiDisplaySink(
-        uint32_t flags,
-        const sp<ANetworkSession> &netSession,
-        const sp<IGraphicBufferProducer> &bufferProducer,
-        const sp<AMessage> &notify)
-    : mState(UNDEFINED),
-      mFlags(flags),
-      mNetSession(netSession),
-      mSurfaceTex(bufferProducer),
-      mNotify(notify),
-      mUsingTCPTransport(false),
-      mUsingTCPInterleaving(false),
-      mSessionID(0),
-      mNextCSeq(1),
-      mIDRFrameRequestPending(false),
-      mTimeOffsetUs(0ll),
-      mTimeOffsetValid(false),
-      mSetupDeferred(false),
-      mLatencyCount(0),
-      mLatencySumUs(0ll),
-      mLatencyMaxUs(0ll),
-      mMaxDelayMs(-1ll) {
-    // We support any and all resolutions, but prefer 720p30
-    mSinkSupportedVideoFormats.setNativeResolution(
-            VideoFormats::RESOLUTION_CEA, 5);  // 1280 x 720 p30
-
-    mSinkSupportedVideoFormats.enableAll();
-}
-
-WifiDisplaySink::~WifiDisplaySink() {
-}
-
-void WifiDisplaySink::start(const char *sourceHost, int32_t sourcePort) {
-    sp<AMessage> msg = new AMessage(kWhatStart, id());
-    msg->setString("sourceHost", sourceHost);
-    msg->setInt32("sourcePort", sourcePort);
-    msg->post();
-}
-
-void WifiDisplaySink::start(const char *uri) {
-    sp<AMessage> msg = new AMessage(kWhatStart, id());
-    msg->setString("setupURI", uri);
-    msg->post();
-}
-
-// static
-bool WifiDisplaySink::ParseURL(
-        const char *url, AString *host, int32_t *port, AString *path,
-        AString *user, AString *pass) {
-    host->clear();
-    *port = 0;
-    path->clear();
-    user->clear();
-    pass->clear();
-
-    if (strncasecmp("rtsp://", url, 7)) {
-        return false;
-    }
-
-    const char *slashPos = strchr(&url[7], '/');
-
-    if (slashPos == NULL) {
-        host->setTo(&url[7]);
-        path->setTo("/");
-    } else {
-        host->setTo(&url[7], slashPos - &url[7]);
-        path->setTo(slashPos);
-    }
-
-    ssize_t atPos = host->find("@");
-
-    if (atPos >= 0) {
-        // Split of user:pass@ from hostname.
-
-        AString userPass(*host, 0, atPos);
-        host->erase(0, atPos + 1);
-
-        ssize_t colonPos = userPass.find(":");
-
-        if (colonPos < 0) {
-            *user = userPass;
-        } else {
-            user->setTo(userPass, 0, colonPos);
-            pass->setTo(userPass, colonPos + 1, userPass.size() - colonPos - 1);
-        }
-    }
-
-    const char *colonPos = strchr(host->c_str(), ':');
-
-    if (colonPos != NULL) {
-        char *end;
-        unsigned long x = strtoul(colonPos + 1, &end, 10);
-
-        if (end == colonPos + 1 || *end != '\0' || x >= 65536) {
-            return false;
-        }
-
-        *port = x;
-
-        size_t colonOffset = colonPos - host->c_str();
-        size_t trailing = host->size() - colonOffset;
-        host->erase(colonOffset, trailing);
-    } else {
-        *port = 554;
-    }
-
-    return true;
-}
-
-void WifiDisplaySink::onMessageReceived(const sp<AMessage> &msg) {
-    switch (msg->what()) {
-        case kWhatStart:
-        {
-            sleep(2);  // XXX
-
-            int32_t sourcePort;
-            CHECK(msg->findString("sourceHost", &mRTSPHost));
-            CHECK(msg->findInt32("sourcePort", &sourcePort));
-
-            sp<AMessage> notify = new AMessage(kWhatRTSPNotify, id());
-
-            status_t err = mNetSession->createRTSPClient(
-                    mRTSPHost.c_str(), sourcePort, notify, &mSessionID);
-            CHECK_EQ(err, (status_t)OK);
-
-            mState = CONNECTING;
-            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));
-
-                    if (sessionID == mSessionID) {
-                        ALOGI("Lost control connection.");
-
-                        // The control connection is dead now.
-                        mNetSession->destroySession(mSessionID);
-                        mSessionID = 0;
-
-                        if (mNotify == NULL) {
-                            looper()->stop();
-                        } else {
-                            sp<AMessage> notify = mNotify->dup();
-                            notify->setInt32("what", kWhatDisconnected);
-                            notify->post();
-                        }
-                    }
-                    break;
-                }
-
-                case ANetworkSession::kWhatConnected:
-                {
-                    ALOGI("We're now connected.");
-                    mState = CONNECTED;
-
-                    if (mFlags & FLAG_SPECIAL_MODE) {
-                        sp<AMessage> notify = new AMessage(
-                                kWhatTimeSyncerNotify, id());
-
-                        mTimeSyncer = new TimeSyncer(mNetSession, notify);
-                        looper()->registerHandler(mTimeSyncer);
-
-                        mTimeSyncer->startClient(mRTSPHost.c_str(), 8123);
-                    }
-                    break;
-                }
-
-                case ANetworkSession::kWhatData:
-                {
-                    onReceiveClientData(msg);
-                    break;
-                }
-
-                default:
-                    TRESPASS();
-            }
-            break;
-        }
-
-        case kWhatStop:
-        {
-            looper()->stop();
-            break;
-        }
-
-        case kWhatMediaReceiverNotify:
-        {
-            onMediaReceiverNotify(msg);
-            break;
-        }
-
-        case kWhatTimeSyncerNotify:
-        {
-            int32_t what;
-            CHECK(msg->findInt32("what", &what));
-
-            if (what == TimeSyncer::kWhatTimeOffset) {
-                CHECK(msg->findInt64("offset", &mTimeOffsetUs));
-                mTimeOffsetValid = true;
-
-                if (mSetupDeferred) {
-                    CHECK_EQ((status_t)OK,
-                             sendSetup(
-                                mSessionID,
-                                "rtsp://x.x.x.x:x/wfd1.0/streamid=0"));
-
-                    mSetupDeferred = false;
-                }
-            }
-            break;
-        }
-
-        case kWhatReportLateness:
-        {
-            if (mLatencyCount > 0) {
-                int64_t avgLatencyUs = mLatencySumUs / mLatencyCount;
-
-                ALOGV("avg. latency = %lld ms (max %lld ms)",
-                      avgLatencyUs / 1000ll,
-                      mLatencyMaxUs / 1000ll);
-
-                sp<AMessage> params = new AMessage;
-                params->setInt64("avgLatencyUs", avgLatencyUs);
-                params->setInt64("maxLatencyUs", mLatencyMaxUs);
-                mMediaReceiver->informSender(0 /* trackIndex */, params);
-            }
-
-            mLatencyCount = 0;
-            mLatencySumUs = 0ll;
-            mLatencyMaxUs = 0ll;
-
-            msg->post(kReportLatenessEveryUs);
-            break;
-        }
-
-        default:
-            TRESPASS();
-    }
-}
-
-void WifiDisplaySink::dumpDelay(size_t trackIndex, int64_t timeUs) {
-    int64_t delayMs = (ALooper::GetNowUs() - timeUs) / 1000ll;
-
-    if (delayMs > mMaxDelayMs) {
-        mMaxDelayMs = delayMs;
-    }
-
-    static const int64_t kMinDelayMs = 0;
-    static const int64_t kMaxDelayMs = 300;
-
-    const char *kPattern = "########################################";
-    size_t kPatternSize = strlen(kPattern);
-
-    int n = (kPatternSize * (delayMs - kMinDelayMs))
-                / (kMaxDelayMs - kMinDelayMs);
-
-    if (n < 0) {
-        n = 0;
-    } else if ((size_t)n > kPatternSize) {
-        n = kPatternSize;
-    }
-
-    ALOGI("[%lld]: (%4lld ms / %4lld ms) %s",
-          timeUs / 1000,
-          delayMs,
-          mMaxDelayMs,
-          kPattern + kPatternSize - n);
-}
-
-void WifiDisplaySink::onMediaReceiverNotify(const sp<AMessage> &msg) {
-    int32_t what;
-    CHECK(msg->findInt32("what", &what));
-
-    switch (what) {
-        case MediaReceiver::kWhatInitDone:
-        {
-            status_t err;
-            CHECK(msg->findInt32("err", &err));
-
-            ALOGI("MediaReceiver initialization completed w/ err %d", err);
-            break;
-        }
-
-        case MediaReceiver::kWhatError:
-        {
-            status_t err;
-            CHECK(msg->findInt32("err", &err));
-
-            ALOGE("MediaReceiver signaled error %d", err);
-            break;
-        }
-
-        case MediaReceiver::kWhatAccessUnit:
-        {
-            if (mRenderer == NULL) {
-                mRenderer = new DirectRenderer(mSurfaceTex);
-                looper()->registerHandler(mRenderer);
-            }
-
-            sp<ABuffer> accessUnit;
-            CHECK(msg->findBuffer("accessUnit", &accessUnit));
-
-            int64_t timeUs;
-            CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
-
-            if (!mTimeOffsetValid && !(mFlags & FLAG_SPECIAL_MODE)) {
-                mTimeOffsetUs = timeUs - ALooper::GetNowUs();
-                mTimeOffsetValid = true;
-            }
-
-            CHECK(mTimeOffsetValid);
-
-            // We are the timesync _client_,
-            // client time = server time - time offset.
-            timeUs -= mTimeOffsetUs;
-
-            size_t trackIndex;
-            CHECK(msg->findSize("trackIndex", &trackIndex));
-
-            int64_t nowUs = ALooper::GetNowUs();
-            int64_t delayUs = nowUs - timeUs;
-
-            mLatencySumUs += delayUs;
-            if (mLatencyCount == 0 || delayUs > mLatencyMaxUs) {
-                mLatencyMaxUs = delayUs;
-            }
-            ++mLatencyCount;
-
-            // dumpDelay(trackIndex, timeUs);
-
-            timeUs += 220000ll;  // Assume 220 ms of latency
-            accessUnit->meta()->setInt64("timeUs", timeUs);
-
-            sp<AMessage> format;
-            if (msg->findMessage("format", &format)) {
-                mRenderer->setFormat(trackIndex, format);
-            }
-
-            mRenderer->queueAccessUnit(trackIndex, accessUnit);
-            break;
-        }
-
-        case MediaReceiver::kWhatPacketLost:
-        {
-#if 0
-            if (!mIDRFrameRequestPending) {
-                ALOGI("requesting IDR frame");
-
-                sendIDRFrameRequest(mSessionID);
-            }
-#endif
-            break;
-        }
-
-        default:
-            TRESPASS();
-    }
-}
-
-void WifiDisplaySink::registerResponseHandler(
-        int32_t sessionID, int32_t cseq, HandleRTSPResponseFunc func) {
-    ResponseID id;
-    id.mSessionID = sessionID;
-    id.mCSeq = cseq;
-    mResponseHandlers.add(id, func);
-}
-
-status_t WifiDisplaySink::sendM2(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, &WifiDisplaySink::onReceiveM2Response);
-
-    ++mNextCSeq;
-
-    return OK;
-}
-
-status_t WifiDisplaySink::onReceiveM2Response(
-        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 WifiDisplaySink::onReceiveSetupResponse(
-        int32_t sessionID, const sp<ParsedMessage> &msg) {
-    int32_t statusCode;
-    if (!msg->getStatusCode(&statusCode)) {
-        return ERROR_MALFORMED;
-    }
-
-    if (statusCode != 200) {
-        return ERROR_UNSUPPORTED;
-    }
-
-    if (!msg->findString("session", &mPlaybackSessionID)) {
-        return ERROR_MALFORMED;
-    }
-
-    if (!ParsedMessage::GetInt32Attribute(
-                mPlaybackSessionID.c_str(),
-                "timeout",
-                &mPlaybackSessionTimeoutSecs)) {
-        mPlaybackSessionTimeoutSecs = -1;
-    }
-
-    ssize_t colonPos = mPlaybackSessionID.find(";");
-    if (colonPos >= 0) {
-        // Strip any options from the returned session id.
-        mPlaybackSessionID.erase(
-                colonPos, mPlaybackSessionID.size() - colonPos);
-    }
-
-    status_t err = configureTransport(msg);
-
-    if (err != OK) {
-        return err;
-    }
-
-    mState = PAUSED;
-
-    return sendPlay(
-            sessionID,
-            "rtsp://x.x.x.x:x/wfd1.0/streamid=0");
-}
-
-status_t WifiDisplaySink::configureTransport(const sp<ParsedMessage> &msg) {
-    if (mUsingTCPTransport && !(mFlags & FLAG_SPECIAL_MODE)) {
-        // In "special" mode we still use a UDP RTCP back-channel that
-        // needs connecting.
-        return OK;
-    }
-
-    AString transport;
-    if (!msg->findString("transport", &transport)) {
-        ALOGE("Missing 'transport' field in SETUP response.");
-        return ERROR_MALFORMED;
-    }
-
-    AString sourceHost;
-    if (!ParsedMessage::GetAttribute(
-                transport.c_str(), "source", &sourceHost)) {
-        sourceHost = mRTSPHost;
-    }
-
-    AString serverPortStr;
-    if (!ParsedMessage::GetAttribute(
-                transport.c_str(), "server_port", &serverPortStr)) {
-        ALOGE("Missing 'server_port' in Transport field.");
-        return ERROR_MALFORMED;
-    }
-
-    int rtpPort, rtcpPort;
-    if (sscanf(serverPortStr.c_str(), "%d-%d", &rtpPort, &rtcpPort) != 2
-            || rtpPort <= 0 || rtpPort > 65535
-            || rtcpPort <=0 || rtcpPort > 65535
-            || rtcpPort != rtpPort + 1) {
-        ALOGE("Invalid server_port description '%s'.",
-                serverPortStr.c_str());
-
-        return ERROR_MALFORMED;
-    }
-
-    if (rtpPort & 1) {
-        ALOGW("Server picked an odd numbered RTP port.");
-    }
-
-    return mMediaReceiver->connectTrack(
-            0 /* trackIndex */, sourceHost.c_str(), rtpPort, rtcpPort);
-}
-
-status_t WifiDisplaySink::onReceivePlayResponse(
-        int32_t sessionID, const sp<ParsedMessage> &msg) {
-    int32_t statusCode;
-    if (!msg->getStatusCode(&statusCode)) {
-        return ERROR_MALFORMED;
-    }
-
-    if (statusCode != 200) {
-        return ERROR_UNSUPPORTED;
-    }
-
-    mState = PLAYING;
-
-    (new AMessage(kWhatReportLateness, id()))->post(kReportLatenessEveryUs);
-
-    return OK;
-}
-
-status_t WifiDisplaySink::onReceiveIDRFrameRequestResponse(
-        int32_t sessionID, const sp<ParsedMessage> &msg) {
-    CHECK(mIDRFrameRequestPending);
-    mIDRFrameRequestPending = false;
-
-    return OK;
-}
-
-void WifiDisplaySink::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);
-        CHECK_EQ(err, (status_t)OK);
-    } else {
-        AString version;
-        data->getRequestField(2, &version);
-        if (!(version == AString("RTSP/1.0"))) {
-            sendErrorResponse(sessionID, "505 RTSP Version not supported", cseq);
-            return;
-        }
-
-        if (method == "OPTIONS") {
-            onOptionsRequest(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 WifiDisplaySink::onOptionsRequest(
-        int32_t sessionID,
-        int32_t cseq,
-        const sp<ParsedMessage> &data) {
-    AString response = "RTSP/1.0 200 OK\r\n";
-    AppendCommonResponse(&response, cseq);
-    response.append("Public: org.wfa.wfd1.0, 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 = sendM2(sessionID);
-    CHECK_EQ(err, (status_t)OK);
-}
-
-void WifiDisplaySink::onGetParameterRequest(
-        int32_t sessionID,
-        int32_t cseq,
-        const sp<ParsedMessage> &data) {
-    AString body;
-
-    if (mState == CONNECTED) {
-        mUsingTCPTransport = false;
-        mUsingTCPInterleaving = false;
-
-        char val[PROPERTY_VALUE_MAX];
-        if (property_get("media.wfd-sink.tcp-mode", val, NULL)) {
-            if (!strcasecmp("true", val) || !strcmp("1", val)) {
-                ALOGI("Using TCP unicast transport.");
-                mUsingTCPTransport = true;
-                mUsingTCPInterleaving = false;
-            } else if (!strcasecmp("interleaved", val)) {
-                ALOGI("Using TCP interleaved transport.");
-                mUsingTCPTransport = true;
-                mUsingTCPInterleaving = true;
-            }
-        } else if (mFlags & FLAG_SPECIAL_MODE) {
-            mUsingTCPTransport = true;
-        }
-
-        body = "wfd_video_formats: ";
-        body.append(mSinkSupportedVideoFormats.getFormatSpec());
-
-        body.append(
-                "\r\nwfd_audio_codecs: AAC 0000000F 00\r\n"
-                "wfd_client_rtp_ports: RTP/AVP/");
-
-        if (mUsingTCPTransport) {
-            body.append("TCP;");
-            if (mUsingTCPInterleaving) {
-                body.append("interleaved");
-            } else {
-                body.append("unicast 19000 0");
-            }
-        } else {
-            body.append("UDP;unicast 19000 0");
-        }
-
-        body.append(" mode=play\r\n");
-    }
-
-    AString response = "RTSP/1.0 200 OK\r\n";
-    AppendCommonResponse(&response, cseq);
-    response.append("Content-Type: text/parameters\r\n");
-    response.append(StringPrintf("Content-Length: %d\r\n", body.size()));
-    response.append("\r\n");
-    response.append(body);
-
-    status_t err = mNetSession->sendRequest(sessionID, response.c_str());
-    CHECK_EQ(err, (status_t)OK);
-}
-
-status_t WifiDisplaySink::sendSetup(int32_t sessionID, const char *uri) {
-    sp<AMessage> notify = new AMessage(kWhatMediaReceiverNotify, id());
-
-    mMediaReceiverLooper = new ALooper;
-    mMediaReceiverLooper->setName("media_receiver");
-
-    mMediaReceiverLooper->start(
-            false /* runOnCallingThread */,
-            false /* canCallJava */,
-            PRIORITY_AUDIO);
-
-    mMediaReceiver = new MediaReceiver(mNetSession, notify);
-    mMediaReceiverLooper->registerHandler(mMediaReceiver);
-
-    RTPReceiver::TransportMode rtpMode = RTPReceiver::TRANSPORT_UDP;
-    if (mUsingTCPTransport) {
-        if (mUsingTCPInterleaving) {
-            rtpMode = RTPReceiver::TRANSPORT_TCP_INTERLEAVED;
-        } else {
-            rtpMode = RTPReceiver::TRANSPORT_TCP;
-        }
-    }
-
-    int32_t localRTPPort;
-    status_t err = mMediaReceiver->addTrack(
-            rtpMode, RTPReceiver::TRANSPORT_UDP /* rtcpMode */, &localRTPPort);
-
-    if (err == OK) {
-        err = mMediaReceiver->initAsync(MediaReceiver::MODE_TRANSPORT_STREAM);
-    }
-
-    if (err != OK) {
-        mMediaReceiverLooper->unregisterHandler(mMediaReceiver->id());
-        mMediaReceiver.clear();
-
-        mMediaReceiverLooper->stop();
-        mMediaReceiverLooper.clear();
-
-        return err;
-    }
-
-    AString request = StringPrintf("SETUP %s RTSP/1.0\r\n", uri);
-
-    AppendCommonResponse(&request, mNextCSeq);
-
-    if (rtpMode == RTPReceiver::TRANSPORT_TCP_INTERLEAVED) {
-        request.append("Transport: RTP/AVP/TCP;interleaved=0-1\r\n");
-    } else if (rtpMode == RTPReceiver::TRANSPORT_TCP) {
-        if (mFlags & FLAG_SPECIAL_MODE) {
-            // This isn't quite true, since the RTP connection is through TCP
-            // and the RTCP connection through UDP...
-            request.append(
-                    StringPrintf(
-                        "Transport: RTP/AVP/TCP;unicast;client_port=%d-%d\r\n",
-                        localRTPPort, localRTPPort + 1));
-        } else {
-            request.append(
-                    StringPrintf(
-                        "Transport: RTP/AVP/TCP;unicast;client_port=%d\r\n",
-                        localRTPPort));
-        }
-    } else {
-        request.append(
-                StringPrintf(
-                    "Transport: RTP/AVP/UDP;unicast;client_port=%d-%d\r\n",
-                    localRTPPort,
-                    localRTPPort + 1));
-    }
-
-    request.append("\r\n");
-
-    ALOGV("request = '%s'", request.c_str());
-
-    err = mNetSession->sendRequest(sessionID, request.c_str(), request.size());
-
-    if (err != OK) {
-        return err;
-    }
-
-    registerResponseHandler(
-            sessionID, mNextCSeq, &WifiDisplaySink::onReceiveSetupResponse);
-
-    ++mNextCSeq;
-
-    return OK;
-}
-
-status_t WifiDisplaySink::sendPlay(int32_t sessionID, const char *uri) {
-    AString request = StringPrintf("PLAY %s RTSP/1.0\r\n", uri);
-
-    AppendCommonResponse(&request, mNextCSeq);
-
-    request.append(StringPrintf("Session: %s\r\n", mPlaybackSessionID.c_str()));
-    request.append("\r\n");
-
-    status_t err =
-        mNetSession->sendRequest(sessionID, request.c_str(), request.size());
-
-    if (err != OK) {
-        return err;
-    }
-
-    registerResponseHandler(
-            sessionID, mNextCSeq, &WifiDisplaySink::onReceivePlayResponse);
-
-    ++mNextCSeq;
-
-    return OK;
-}
-
-status_t WifiDisplaySink::sendIDRFrameRequest(int32_t sessionID) {
-    CHECK(!mIDRFrameRequestPending);
-
-    AString request = "SET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0\r\n";
-
-    AppendCommonResponse(&request, mNextCSeq);
-
-    AString content = "wfd_idr_request\r\n";
-
-    request.append(StringPrintf("Session: %s\r\n", mPlaybackSessionID.c_str()));
-    request.append(StringPrintf("Content-Length: %d\r\n", content.size()));
-    request.append("\r\n");
-    request.append(content);
-
-    status_t err =
-        mNetSession->sendRequest(sessionID, request.c_str(), request.size());
-
-    if (err != OK) {
-        return err;
-    }
-
-    registerResponseHandler(
-            sessionID,
-            mNextCSeq,
-            &WifiDisplaySink::onReceiveIDRFrameRequestResponse);
-
-    ++mNextCSeq;
-
-    mIDRFrameRequestPending = true;
-
-    return OK;
-}
-
-void WifiDisplaySink::onSetParameterRequest(
-        int32_t sessionID,
-        int32_t cseq,
-        const sp<ParsedMessage> &data) {
-    const char *content = data->getContent();
-
-    if (strstr(content, "wfd_trigger_method: SETUP\r\n") != NULL) {
-        if ((mFlags & FLAG_SPECIAL_MODE) && !mTimeOffsetValid) {
-            mSetupDeferred = true;
-        } else {
-            status_t err =
-                sendSetup(
-                        sessionID,
-                        "rtsp://x.x.x.x:x/wfd1.0/streamid=0");
-
-            CHECK_EQ(err, (status_t)OK);
-        }
-    }
-
-    AString response = "RTSP/1.0 200 OK\r\n";
-    AppendCommonResponse(&response, cseq);
-    response.append("\r\n");
-
-    status_t err = mNetSession->sendRequest(sessionID, response.c_str());
-    CHECK_EQ(err, (status_t)OK);
-}
-
-void WifiDisplaySink::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);
-}
-
-// static
-void WifiDisplaySink::AppendCommonResponse(AString *response, int32_t cseq) {
-    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(StringPrintf("User-Agent: %s\r\n", sUserAgent.c_str()));
-
-    if (cseq >= 0) {
-        response->append(StringPrintf("CSeq: %d\r\n", cseq));
-    }
-}
-
-}  // namespace android
diff --git a/media/libstagefright/wifi-display/sink/WifiDisplaySink.h b/media/libstagefright/wifi-display/sink/WifiDisplaySink.h
deleted file mode 100644
index dc1fc32..0000000
--- a/media/libstagefright/wifi-display/sink/WifiDisplaySink.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * 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_SINK_H_
-
-#define WIFI_DISPLAY_SINK_H_
-
-#include "VideoFormats.h"
-
-#include <gui/Surface.h>
-#include <media/stagefright/foundation/AHandler.h>
-#include <media/stagefright/foundation/ANetworkSession.h>
-
-namespace android {
-
-struct AMessage;
-struct DirectRenderer;
-struct MediaReceiver;
-struct ParsedMessage;
-struct TimeSyncer;
-
-// Represents the RTSP client acting as a wifi display sink.
-// Connects to a wifi display source and renders the incoming
-// transport stream using a MediaPlayer instance.
-struct WifiDisplaySink : public AHandler {
-    enum {
-        kWhatDisconnected,
-    };
-
-    enum Flags {
-        FLAG_SPECIAL_MODE = 1,
-    };
-
-    // If no notification message is specified (notify == NULL)
-    // the sink will stop its looper() once the session ends,
-    // otherwise it will post an appropriate notification but leave
-    // the looper() running.
-    WifiDisplaySink(
-            uint32_t flags,
-            const sp<ANetworkSession> &netSession,
-            const sp<IGraphicBufferProducer> &bufferProducer = NULL,
-            const sp<AMessage> &notify = NULL);
-
-    void start(const char *sourceHost, int32_t sourcePort);
-    void start(const char *uri);
-
-protected:
-    virtual ~WifiDisplaySink();
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
-    enum State {
-        UNDEFINED,
-        CONNECTING,
-        CONNECTED,
-        PAUSED,
-        PLAYING,
-    };
-
-    enum {
-        kWhatStart,
-        kWhatRTSPNotify,
-        kWhatStop,
-        kWhatMediaReceiverNotify,
-        kWhatTimeSyncerNotify,
-        kWhatReportLateness,
-    };
-
-    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 (WifiDisplaySink::*HandleRTSPResponseFunc)(
-            int32_t sessionID, const sp<ParsedMessage> &msg);
-
-    static const int64_t kReportLatenessEveryUs = 1000000ll;
-
-    static const AString sUserAgent;
-
-    State mState;
-    uint32_t mFlags;
-    VideoFormats mSinkSupportedVideoFormats;
-    sp<ANetworkSession> mNetSession;
-    sp<IGraphicBufferProducer> mSurfaceTex;
-    sp<AMessage> mNotify;
-    sp<TimeSyncer> mTimeSyncer;
-    bool mUsingTCPTransport;
-    bool mUsingTCPInterleaving;
-    AString mRTSPHost;
-    int32_t mSessionID;
-
-    int32_t mNextCSeq;
-
-    KeyedVector<ResponseID, HandleRTSPResponseFunc> mResponseHandlers;
-
-    sp<ALooper> mMediaReceiverLooper;
-    sp<MediaReceiver> mMediaReceiver;
-    sp<DirectRenderer> mRenderer;
-
-    AString mPlaybackSessionID;
-    int32_t mPlaybackSessionTimeoutSecs;
-
-    bool mIDRFrameRequestPending;
-
-    int64_t mTimeOffsetUs;
-    bool mTimeOffsetValid;
-
-    bool mSetupDeferred;
-
-    size_t mLatencyCount;
-    int64_t mLatencySumUs;
-    int64_t mLatencyMaxUs;
-
-    int64_t mMaxDelayMs;
-
-    status_t sendM2(int32_t sessionID);
-    status_t sendSetup(int32_t sessionID, const char *uri);
-    status_t sendPlay(int32_t sessionID, const char *uri);
-    status_t sendIDRFrameRequest(int32_t sessionID);
-
-    status_t onReceiveM2Response(
-            int32_t sessionID, const sp<ParsedMessage> &msg);
-
-    status_t onReceiveSetupResponse(
-            int32_t sessionID, const sp<ParsedMessage> &msg);
-
-    status_t configureTransport(const sp<ParsedMessage> &msg);
-
-    status_t onReceivePlayResponse(
-            int32_t sessionID, const sp<ParsedMessage> &msg);
-
-    status_t onReceiveIDRFrameRequestResponse(
-            int32_t sessionID, const sp<ParsedMessage> &msg);
-
-    void registerResponseHandler(
-            int32_t sessionID, int32_t cseq, HandleRTSPResponseFunc func);
-
-    void onReceiveClientData(const sp<AMessage> &msg);
-
-    void onOptionsRequest(
-            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 onMediaReceiverNotify(const sp<AMessage> &msg);
-
-    void sendErrorResponse(
-            int32_t sessionID,
-            const char *errorDetail,
-            int32_t cseq);
-
-    static void AppendCommonResponse(AString *response, int32_t cseq);
-
-    bool ParseURL(
-            const char *url, AString *host, int32_t *port, AString *path,
-            AString *user, AString *pass);
-
-    void dumpDelay(size_t trackIndex, int64_t timeUs);
-
-    DISALLOW_EVIL_CONSTRUCTORS(WifiDisplaySink);
-};
-
-}  // namespace android
-
-#endif  // WIFI_DISPLAY_SINK_H_
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
index d72349d..05e4018 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
@@ -22,7 +22,6 @@
 #include "PlaybackSession.h"
 #include "Parameters.h"
 #include "rtp/RTPSender.h"
-#include "TimeSyncer.h"
 
 #include <binder/IServiceManager.h>
 #include <gui/IGraphicBufferProducer.h>
@@ -173,15 +172,7 @@
                 }
             }
 
-            if (err == OK) {
-                sp<AMessage> notify = new AMessage(kWhatTimeSyncerNotify, id());
-                mTimeSyncer = new TimeSyncer(mNetSession, notify);
-                looper()->registerHandler(mTimeSyncer);
-
-                mTimeSyncer->startServer(8123);
-
-                mState = AWAITING_CLIENT_CONNECTION;
-            }
+            mState = AWAITING_CLIENT_CONNECTION;
 
             sp<AMessage> response = new AMessage;
             response->setInt32("err", err);
@@ -556,11 +547,6 @@
             break;
         }
 
-        case kWhatTimeSyncerNotify:
-        {
-            break;
-        }
-
         default:
             TRESPASS();
     }
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.h b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
index 4f11712..750265f 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.h
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
@@ -30,7 +30,6 @@
 struct IHDCP;
 struct IRemoteDisplayClient;
 struct ParsedMessage;
-struct TimeSyncer;
 
 // Represents the RTSP server acting as a wifi display source.
 // Manages incoming connections, sets up Playback sessions as necessary.
@@ -83,7 +82,6 @@
         kWhatHDCPNotify,
         kWhatFinishStop2,
         kWhatTeardownTriggerTimedOut,
-        kWhatTimeSyncerNotify,
     };
 
     struct ResponseID {
@@ -120,7 +118,6 @@
     sp<ANetworkSession> mNetSession;
     sp<IRemoteDisplayClient> mClient;
     AString mMediaPath;
-    sp<TimeSyncer> mTimeSyncer;
     struct in_addr mInterfaceAddr;
     int32_t mSessionID;
 
diff --git a/media/libstagefright/wifi-display/udptest.cpp b/media/libstagefright/wifi-display/udptest.cpp
deleted file mode 100644
index 61eb9f9..0000000
--- a/media/libstagefright/wifi-display/udptest.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * 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_NEBUG 0
-#define LOG_TAG "udptest"
-#include <utils/Log.h>
-
-#include "TimeSyncer.h"
-
-#include <binder/ProcessState.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/ANetworkSession.h>
-
-namespace android {
-
-}  // namespace android
-
-static void usage(const char *me) {
-    fprintf(stderr,
-            "usage: %s -c host[:port]\tconnect to test server\n"
-            "           -l            \tcreate a test server\n",
-            me);
-}
-
-int main(int argc, char **argv) {
-    using namespace android;
-
-    ProcessState::self()->startThreadPool();
-
-    int32_t localPort = -1;
-    int32_t connectToPort = -1;
-    AString connectToHost;
-
-    int res;
-    while ((res = getopt(argc, argv, "hc:l:")) >= 0) {
-        switch (res) {
-            case 'c':
-            {
-                const char *colonPos = strrchr(optarg, ':');
-
-                if (colonPos == NULL) {
-                    connectToHost = optarg;
-                    connectToPort = 49152;
-                } 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 'l':
-            {
-                char *end;
-                localPort = strtol(optarg, &end, 10);
-
-                if (*end != '\0' || end == optarg
-                        || localPort < 1 || localPort > 65535) {
-                    fprintf(stderr, "Illegal port specified.\n");
-                    exit(1);
-                }
-                break;
-            }
-
-            case '?':
-            case 'h':
-                usage(argv[0]);
-                exit(1);
-        }
-    }
-
-    if (localPort < 0 && connectToPort < 0) {
-        fprintf(stderr,
-                "You need to select either client or server mode.\n");
-        exit(1);
-    }
-
-    sp<ANetworkSession> netSession = new ANetworkSession;
-    netSession->start();
-
-    sp<ALooper> looper = new ALooper;
-
-    sp<TimeSyncer> handler = new TimeSyncer(netSession, NULL /* notify */);
-    looper->registerHandler(handler);
-
-    if (localPort >= 0) {
-        handler->startServer(localPort);
-    } else {
-        handler->startClient(connectToHost.c_str(), connectToPort);
-    }
-
-    looper->start(true /* runOnCallingThread */);
-
-    return 0;
-}
-
diff --git a/media/libstagefright/wifi-display/wfd.cpp b/media/libstagefright/wifi-display/wfd.cpp
deleted file mode 100644
index 52e4e26..0000000
--- a/media/libstagefright/wifi-display/wfd.cpp
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * 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>
-
-#include "sink/WifiDisplaySink.h"
-#include "source/WifiDisplaySource.h"
-
-#include <binder/ProcessState.h>
-#include <binder/IServiceManager.h>
-#include <gui/ISurfaceComposer.h>
-#include <gui/SurfaceComposerClient.h>
-#include <media/AudioSystem.h>
-#include <media/IMediaPlayerService.h>
-#include <media/IRemoteDisplay.h>
-#include <media/IRemoteDisplayClient.h>
-#include <media/stagefright/DataSource.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <ui/DisplayInfo.h>
-
-namespace android {
-
-static void usage(const char *me) {
-    fprintf(stderr,
-            "usage:\n"
-            "           %s -c host[:port]\tconnect to wifi source\n"
-            "               -u uri        \tconnect to an rtsp uri\n"
-            "               -l ip[:port] \tlisten on the specified port "
-            "               -f(ilename)  \tstream media "
-            "(create a sink)\n"
-            "               -s(pecial)   \trun in 'special' mode\n",
-            me);
-}
-
-struct RemoteDisplayClient : public BnRemoteDisplayClient {
-    RemoteDisplayClient();
-
-    virtual void onDisplayConnected(
-            const sp<IGraphicBufferProducer> &bufferProducer,
-            uint32_t width,
-            uint32_t height,
-            uint32_t flags,
-            uint32_t session);
-
-    virtual void onDisplayDisconnected();
-    virtual void onDisplayError(int32_t error);
-
-    void waitUntilDone();
-
-protected:
-    virtual ~RemoteDisplayClient();
-
-private:
-    Mutex mLock;
-    Condition mCondition;
-
-    bool mDone;
-
-    sp<SurfaceComposerClient> mComposerClient;
-    sp<IGraphicBufferProducer> mSurfaceTexture;
-    sp<IBinder> mDisplayBinder;
-
-    DISALLOW_EVIL_CONSTRUCTORS(RemoteDisplayClient);
-};
-
-RemoteDisplayClient::RemoteDisplayClient()
-    : mDone(false) {
-    mComposerClient = new SurfaceComposerClient;
-    CHECK_EQ(mComposerClient->initCheck(), (status_t)OK);
-}
-
-RemoteDisplayClient::~RemoteDisplayClient() {
-}
-
-void RemoteDisplayClient::onDisplayConnected(
-        const sp<IGraphicBufferProducer> &bufferProducer,
-        uint32_t width,
-        uint32_t height,
-        uint32_t flags,
-        uint32_t session) {
-    ALOGI("onDisplayConnected width=%u, height=%u, flags = 0x%08x, session = %d",
-          width, height, flags, session);
-
-    if (bufferProducer != NULL) {
-        mSurfaceTexture = bufferProducer;
-        mDisplayBinder = mComposerClient->createDisplay(
-                String8("foo"), false /* secure */);
-
-        SurfaceComposerClient::openGlobalTransaction();
-        mComposerClient->setDisplaySurface(mDisplayBinder, mSurfaceTexture);
-
-        Rect layerStackRect(1280, 720);  // XXX fix this.
-        Rect displayRect(1280, 720);
-
-        mComposerClient->setDisplayProjection(
-                mDisplayBinder, 0 /* 0 degree rotation */,
-                layerStackRect,
-                displayRect);
-
-        SurfaceComposerClient::closeGlobalTransaction();
-    }
-}
-
-void RemoteDisplayClient::onDisplayDisconnected() {
-    ALOGI("onDisplayDisconnected");
-
-    Mutex::Autolock autoLock(mLock);
-    mDone = true;
-    mCondition.broadcast();
-}
-
-void RemoteDisplayClient::onDisplayError(int32_t error) {
-    ALOGI("onDisplayError error=%d", error);
-
-    Mutex::Autolock autoLock(mLock);
-    mDone = true;
-    mCondition.broadcast();
-}
-
-void RemoteDisplayClient::waitUntilDone() {
-    Mutex::Autolock autoLock(mLock);
-    while (!mDone) {
-        mCondition.wait(mLock);
-    }
-}
-
-static void createSource(const AString &addr, int32_t port) {
-    sp<IServiceManager> sm = defaultServiceManager();
-    sp<IBinder> binder = sm->getService(String16("media.player"));
-    sp<IMediaPlayerService> service =
-        interface_cast<IMediaPlayerService>(binder);
-
-    CHECK(service.get() != NULL);
-
-    String8 iface;
-    iface.append(addr.c_str());
-    iface.append(StringPrintf(":%d", port).c_str());
-
-    sp<RemoteDisplayClient> client = new RemoteDisplayClient;
-    sp<IRemoteDisplay> display =
-        service->listenForRemoteDisplay(client, iface);
-
-    client->waitUntilDone();
-
-    display->dispose();
-    display.clear();
-}
-
-static void createFileSource(
-        const AString &addr, int32_t port, const char *path) {
-    sp<ANetworkSession> session = new ANetworkSession;
-    session->start();
-
-    sp<ALooper> looper = new ALooper;
-    looper->start();
-
-    sp<RemoteDisplayClient> client = new RemoteDisplayClient;
-    sp<WifiDisplaySource> source = new WifiDisplaySource(session, client, path);
-    looper->registerHandler(source);
-
-    AString iface = StringPrintf("%s:%d", addr.c_str(), port);
-    CHECK_EQ((status_t)OK, source->start(iface.c_str()));
-
-    client->waitUntilDone();
-
-    source->stop();
-}
-
-}  // namespace android
-
-int main(int argc, char **argv) {
-    using namespace android;
-
-    ProcessState::self()->startThreadPool();
-
-    DataSource::RegisterDefaultSniffers();
-
-    AString connectToHost;
-    int32_t connectToPort = -1;
-    AString uri;
-
-    AString listenOnAddr;
-    int32_t listenOnPort = -1;
-
-    AString path;
-
-    bool specialMode = false;
-
-    int res;
-    while ((res = getopt(argc, argv, "hc:l:u:f:s")) >= 0) {
-        switch (res) {
-            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;
-            }
-
-            case 'f':
-            {
-                path = optarg;
-                break;
-            }
-
-            case 'l':
-            {
-                const char *colonPos = strrchr(optarg, ':');
-
-                if (colonPos == NULL) {
-                    listenOnAddr = optarg;
-                    listenOnPort = WifiDisplaySource::kWifiDisplayDefaultPort;
-                } else {
-                    listenOnAddr.setTo(optarg, colonPos - optarg);
-
-                    char *end;
-                    listenOnPort = strtol(colonPos + 1, &end, 10);
-
-                    if (*end != '\0' || end == colonPos + 1
-                            || listenOnPort < 1 || listenOnPort > 65535) {
-                        fprintf(stderr, "Illegal port specified.\n");
-                        exit(1);
-                    }
-                }
-                break;
-            }
-
-            case 's':
-            {
-                specialMode = true;
-                break;
-            }
-
-            case '?':
-            case 'h':
-            default:
-                usage(argv[0]);
-                exit(1);
-        }
-    }
-
-    if (connectToPort >= 0 && listenOnPort >= 0) {
-        fprintf(stderr,
-                "You can connect to a source or create one, "
-                "but not both at the same time.\n");
-        exit(1);
-    }
-
-    if (listenOnPort >= 0) {
-        if (path.empty()) {
-            createSource(listenOnAddr, listenOnPort);
-        } else {
-            createFileSource(listenOnAddr, listenOnPort, path.c_str());
-        }
-
-        exit(0);
-    }
-
-    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<SurfaceComposerClient> composerClient = new SurfaceComposerClient;
-    CHECK_EQ(composerClient->initCheck(), (status_t)OK);
-
-    sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(
-            ISurfaceComposer::eDisplayIdMain));
-    DisplayInfo info;
-    SurfaceComposerClient::getDisplayInfo(display, &info);
-    ssize_t displayWidth = info.w;
-    ssize_t displayHeight = info.h;
-
-    ALOGV("display is %d x %d\n", displayWidth, displayHeight);
-
-    sp<SurfaceControl> control =
-        composerClient->createSurface(
-                String8("A Surface"),
-                displayWidth,
-                displayHeight,
-                PIXEL_FORMAT_RGB_565,
-                0);
-
-    CHECK(control != NULL);
-    CHECK(control->isValid());
-
-    SurfaceComposerClient::openGlobalTransaction();
-    CHECK_EQ(control->setLayer(INT_MAX), (status_t)OK);
-    CHECK_EQ(control->show(), (status_t)OK);
-    SurfaceComposerClient::closeGlobalTransaction();
-
-    sp<Surface> surface = control->getSurface();
-    CHECK(surface != NULL);
-
-    sp<ANetworkSession> session = new ANetworkSession;
-    session->start();
-
-    sp<ALooper> looper = new ALooper;
-
-    sp<WifiDisplaySink> sink = new WifiDisplaySink(
-            specialMode ? WifiDisplaySink::FLAG_SPECIAL_MODE : 0 /* flags */,
-            session,
-            surface->getIGraphicBufferProducer());
-
-    looper->registerHandler(sink);
-
-    if (connectToPort >= 0) {
-        sink->start(connectToHost.c_str(), connectToPort);
-    } else {
-        sink->start(uri.c_str());
-    }
-
-    looper->start(true /* runOnCallingThread */);
-
-    composerClient->dispose();
-
-    return 0;
-}
