diff --git a/media/libstagefright/wifi-display/Android.mk b/media/libstagefright/wifi-display/Android.mk
index f99ef60..061ae89 100644
--- a/media/libstagefright/wifi-display/Android.mk
+++ b/media/libstagefright/wifi-display/Android.mk
@@ -4,17 +4,10 @@
 
 LOCAL_SRC_FILES:= \
         ANetworkSession.cpp             \
-        MediaReceiver.cpp               \
         MediaSender.cpp                 \
         Parameters.cpp                  \
         ParsedMessage.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      \
@@ -67,72 +60,3 @@
 LOCAL_MODULE_TAGS := debug
 
 include $(BUILD_EXECUTABLE)
-
-################################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-        udptest.cpp                 \
-
-LOCAL_SHARED_LIBRARIES:= \
-        libbinder                       \
-        libgui                          \
-        libmedia                        \
-        libstagefright                  \
-        libstagefright_foundation       \
-        libstagefright_wfd              \
-        libutils                        \
-        liblog                          \
-
-LOCAL_MODULE:= udptest
-
-LOCAL_MODULE_TAGS := debug
-
-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
-
-LOCAL_MODULE_TAGS := debug
-
-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
-
-LOCAL_MODULE_TAGS := debug
-
-include $(BUILD_EXECUTABLE)
diff --git a/media/libstagefright/wifi-display/MediaReceiver.cpp b/media/libstagefright/wifi-display/MediaReceiver.cpp
deleted file mode 100644
index 364acb9..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 "ANetworkSession.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/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/MediaSender.cpp b/media/libstagefright/wifi-display/MediaSender.cpp
index 33af66d..8a3566f 100644
--- a/media/libstagefright/wifi-display/MediaSender.cpp
+++ b/media/libstagefright/wifi-display/MediaSender.cpp
@@ -341,22 +341,6 @@
             break;
         }
 
-        case kWhatInformSender:
-        {
-            int64_t avgLatencyUs;
-            CHECK(msg->findInt64("avgLatencyUs", &avgLatencyUs));
-
-            int64_t maxLatencyUs;
-            CHECK(msg->findInt64("maxLatencyUs", &maxLatencyUs));
-
-            sp<AMessage> notify = mNotify->dup();
-            notify->setInt32("what", kWhatInformSender);
-            notify->setInt64("avgLatencyUs", avgLatencyUs);
-            notify->setInt64("maxLatencyUs", maxLatencyUs);
-            notify->post();
-            break;
-        }
-
         default:
             TRESPASS();
     }
diff --git a/media/libstagefright/wifi-display/MediaSender.h b/media/libstagefright/wifi-display/MediaSender.h
index 04538ea..64722c5 100644
--- a/media/libstagefright/wifi-display/MediaSender.h
+++ b/media/libstagefright/wifi-display/MediaSender.h
@@ -43,7 +43,6 @@
         kWhatInitDone,
         kWhatError,
         kWhatNetworkStall,
-        kWhatInformSender,
     };
 
     MediaSender(
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 cb429bc..0000000
--- a/media/libstagefright/wifi-display/TimeSyncer.cpp
+++ /dev/null
@@ -1,338 +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 "ANetworkSession.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/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 0779bf5..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 "ANetworkSession.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/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 8fa1dae..0000000
--- a/media/libstagefright/wifi-display/rtp/RTPReceiver.cpp
+++ /dev/null
@@ -1,1153 +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 "ANetworkSession.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>
-#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;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-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() {
-#if 0
-    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());
-#endif
-
-    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/rtp/RTPSender.cpp b/media/libstagefright/wifi-display/rtp/RTPSender.cpp
index 6bbe650..095fd97 100644
--- a/media/libstagefright/wifi-display/rtp/RTPSender.cpp
+++ b/media/libstagefright/wifi-display/rtp/RTPSender.cpp
@@ -767,17 +767,6 @@
 }
 
 status_t RTPSender::parseAPP(const uint8_t *data, size_t size) {
-    if (!memcmp("late", &data[8], 4)) {
-        int64_t avgLatencyUs = (int64_t)U64_AT(&data[12]);
-        int64_t maxLatencyUs = (int64_t)U64_AT(&data[20]);
-
-        sp<AMessage> notify = mNotify->dup();
-        notify->setInt32("what", kWhatInformSender);
-        notify->setInt64("avgLatencyUs", avgLatencyUs);
-        notify->setInt64("maxLatencyUs", maxLatencyUs);
-        notify->post();
-    }
-
     return OK;
 }
 
diff --git a/media/libstagefright/wifi-display/rtp/RTPSender.h b/media/libstagefright/wifi-display/rtp/RTPSender.h
index fefcab7..7dc138a 100644
--- a/media/libstagefright/wifi-display/rtp/RTPSender.h
+++ b/media/libstagefright/wifi-display/rtp/RTPSender.h
@@ -37,7 +37,6 @@
         kWhatInitDone,
         kWhatError,
         kWhatNetworkStall,
-        kWhatInformSender,
     };
     RTPSender(
             const sp<ANetworkSession> &netSession,
diff --git a/media/libstagefright/wifi-display/rtptest.cpp b/media/libstagefright/wifi-display/rtptest.cpp
deleted file mode 100644
index 764a38b..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 "ANetworkSession.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/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 15f9c88..0000000
--- a/media/libstagefright/wifi-display/sink/DirectRenderer.cpp
+++ /dev/null
@@ -1,625 +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/MediaErrors.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/Utils.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;
-        }
-
-        default:
-            TRESPASS();
-    }
-}
-
-void DirectRenderer::setFormat(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) {
-    CHECK_LT(trackIndex, 2u);
-
-    if (mDecoderContext[trackIndex] == NULL) {
-        CHECK_EQ(trackIndex, 0u);
-
-        sp<AMessage> format = new AMessage;
-        format->setString("mime", "video/avc");
-        format->setInt32("width", 640);
-        format->setInt32("height", 360);
-
-        setFormat(trackIndex, format);
-    }
-
-    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 c5a4a83..0000000
--- a/media/libstagefright/wifi-display/sink/DirectRenderer.h
+++ /dev/null
@@ -1,82 +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 AudioTrack;
-struct IGraphicBufferProducer;
-struct MediaCodec;
-
-// 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,
-    };
-
-    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();
-
-    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 5db2099..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 "ParsedMessage.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/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 adb9d89..0000000
--- a/media/libstagefright/wifi-display/sink/WifiDisplaySink.h
+++ /dev/null
@@ -1,196 +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 "ANetworkSession.h"
-
-#include "VideoFormats.h"
-
-#include <gui/Surface.h>
-#include <media/stagefright/foundation/AHandler.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/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
index cacfcca..3d7b865 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
@@ -559,8 +559,6 @@
                         converter->dropAFrame();
                     }
                 }
-            } else if (what == MediaSender::kWhatInformSender) {
-                onSinkFeedback(msg);
             } else {
                 TRESPASS();
             }
@@ -656,89 +654,6 @@
     }
 }
 
-void WifiDisplaySource::PlaybackSession::onSinkFeedback(const sp<AMessage> &msg) {
-    int64_t avgLatencyUs;
-    CHECK(msg->findInt64("avgLatencyUs", &avgLatencyUs));
-
-    int64_t maxLatencyUs;
-    CHECK(msg->findInt64("maxLatencyUs", &maxLatencyUs));
-
-    ALOGI("sink reports avg. latency of %lld ms (max %lld ms)",
-          avgLatencyUs / 1000ll,
-          maxLatencyUs / 1000ll);
-
-    if (mVideoTrackIndex >= 0) {
-        const sp<Track> &videoTrack = mTracks.valueFor(mVideoTrackIndex);
-        sp<Converter> converter = videoTrack->converter();
-
-        if (converter != NULL) {
-            int32_t videoBitrate =
-                Converter::GetInt32Property("media.wfd.video-bitrate", -1);
-
-            char val[PROPERTY_VALUE_MAX];
-            if (videoBitrate < 0
-                    && property_get("media.wfd.video-bitrate", val, NULL)
-                    && !strcasecmp("adaptive", val)) {
-                videoBitrate = converter->getVideoBitrate();
-
-                if (avgLatencyUs > 300000ll) {
-                    videoBitrate *= 0.6;
-                } else if (avgLatencyUs < 100000ll) {
-                    videoBitrate *= 1.1;
-                }
-            }
-
-            if (videoBitrate > 0) {
-                if (videoBitrate < 500000) {
-                    videoBitrate = 500000;
-                } else if (videoBitrate > 10000000) {
-                    videoBitrate = 10000000;
-                }
-
-                if (videoBitrate != converter->getVideoBitrate()) {
-                    ALOGI("setting video bitrate to %d bps", videoBitrate);
-
-                    converter->setVideoBitrate(videoBitrate);
-                }
-            }
-        }
-
-        sp<RepeaterSource> repeaterSource = videoTrack->repeaterSource();
-        if (repeaterSource != NULL) {
-            double rateHz =
-                Converter::GetInt32Property(
-                        "media.wfd.video-framerate", -1);
-
-            char val[PROPERTY_VALUE_MAX];
-            if (rateHz < 0.0
-                    && property_get("media.wfd.video-framerate", val, NULL)
-                    && !strcasecmp("adaptive", val)) {
-                 rateHz = repeaterSource->getFrameRate();
-
-                if (avgLatencyUs > 300000ll) {
-                    rateHz *= 0.9;
-                } else if (avgLatencyUs < 200000ll) {
-                    rateHz *= 1.1;
-                }
-            }
-
-            if (rateHz > 0) {
-                if (rateHz < 5.0) {
-                    rateHz = 5.0;
-                } else if (rateHz > 30.0) {
-                    rateHz = 30.0;
-                }
-
-                if (rateHz != repeaterSource->getFrameRate()) {
-                    ALOGI("setting frame rate to %.2f Hz", rateHz);
-
-                    repeaterSource->setFrameRate(rateHz);
-                }
-            }
-        }
-    }
-}
-
 status_t WifiDisplaySource::PlaybackSession::setupMediaPacketizer(
         bool enableAudio, bool enableVideo) {
     DataSource::RegisterDefaultSniffers();
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
index 4a49811..2b5bee9 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
@@ -23,7 +23,6 @@
 #include "Parameters.h"
 #include "ParsedMessage.h"
 #include "rtp/RTPSender.h"
-#include "TimeSyncer.h"
 
 #include <binder/IServiceManager.h>
 #include <gui/IGraphicBufferProducer.h>
@@ -165,14 +164,6 @@
                 } else {
                     err = -EINVAL;
                 }
-            }
-
-            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;
             }
@@ -548,11 +539,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 3efa0b4..44d3e4d 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 111846d..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 "ANetworkSession.h"
-#include "TimeSyncer.h"
-
-#include <binder/ProcessState.h>
-#include <media/stagefright/foundation/AMessage.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
index 9fee4d0..c947765 100644
--- a/media/libstagefright/wifi-display/wfd.cpp
+++ b/media/libstagefright/wifi-display/wfd.cpp
@@ -18,7 +18,6 @@
 #define LOG_TAG "wfd"
 #include <utils/Log.h>
 
-#include "sink/WifiDisplaySink.h"
 #include "source/WifiDisplaySource.h"
 
 #include <binder/ProcessState.h>
@@ -39,12 +38,8 @@
 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",
+            "           %s -l iface[:port]\tcreate a wifi display source\n"
+            "               -f(ilename)  \tstream media\n",
             me);
 }
 
@@ -214,48 +209,14 @@
 
     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) {
+    while ((res = getopt(argc, argv, "hl:f:")) >= 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;
@@ -284,12 +245,6 @@
                 break;
             }
 
-            case 's':
-            {
-                specialMode = true;
-                break;
-            }
-
             case '?':
             case 'h':
             default:
@@ -298,13 +253,6 @@
         }
     }
 
-    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);
@@ -315,72 +263,7 @@
         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();
+    usage(argv[0]);
 
     return 0;
 }
