Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a556c482 authored by Andreas Huber's avatar Andreas Huber
Browse files

Squashed commit of the following:

commit e5919b1f57ea61fa1d380dfdb4e3e832ce73d79d
Author: Andreas Huber <andih@google.com>
Date:   Wed Feb 27 16:38:48 2013 -0800

    Configure TCP datagram sockets to be TCP_NODELAY.

    Change-Id: Ia724a81e6e27dccd00ac84603e712d69ca77a0cd

commit 1b52b393183db8a6dc000a7c31baac544ccfc50c
Author: Andreas Huber <andih@google.com>
Date:   Wed Feb 27 14:26:01 2013 -0800

    Send IDR frame requests on packet loss.

    Change-Id: I53b7fb85cbd6923491113b93ec3e2175726d654a

commit 68d76b4b3a0181b30abc57cd2915273210530a6d
Author: Andreas Huber <andih@google.com>
Date:   Tue Feb 26 15:12:34 2013 -0800

    Revive TunnelRenderer

    Change-Id: I8c5a9d982793b1c5b841c828227b354f1dab618c

commit 3df28a8e9d8bcdc1430016bb088d097eca653b56
Author: Andreas Huber <andih@google.com>
Date:   Tue Feb 26 13:53:14 2013 -0800

    Disable suspension of video updates.

    Change-Id: I7e3a16b8d7dd7a55d9f962a2236388931f664106

commit 2ec7a79de019a26ec415016c1478afd762f069cd
Author: Andreas Huber <andih@google.com>
Date:   Tue Feb 26 08:54:40 2013 -0800

    Adds an SNTP client to wfd.

    Change-Id: Icd7d6104e951e1443e4c1b81ccf6b3731d79d3ec

commit c81c3bb5725bb4079a4d7fb02151ad0bb540632f
Author: Andreas Huber <andih@google.com>
Date:   Mon Feb 25 10:00:58 2013 -0800

    Squashed commit of the following:

    commit b83a4ec96659ef6f6b7c2090fdd866abe3ab78ba
    Author: Andreas Huber <andih@google.com>
    Date:   Mon Feb 25 09:28:11 2013 -0800

        Some reorganization of the rtp code, renamed StreamHub -> MediaSender

        Change-Id: I8cf67444960e60426bf74880af1acce41e8b2fef

    commit 7769cbd739f2a67c58e0c6a7b1a21a12210c7c4d
    Author: Andreas Huber <andih@google.com>
    Date:   Fri Feb 22 16:12:18 2013 -0800

        Choose a smaller MTU to avoid fragmented IPv4 packets, fix AVC assembler.

        Change-Id: I274b3cc1483c4e9f4d146dbf9f3d9f7557ef7ef9

    commit 1f687ee80a88b56d614c2cf408ff729114ff86a0
    Author: Andreas Huber <andih@google.com>
    Date:   Fri Feb 22 11:38:31 2013 -0800

        better reporting.

        Change-Id: I67f0bb51f106ea77f5cc75938b053c8e8e8f688e

    commit 7950c1cd59213eb5f281fcde44a772ecffae473d
    Author: Andreas Huber <andih@google.com>
    Date:   Fri Feb 22 09:07:41 2013 -0800

        stuff

        Change-Id: Ib99416366d3eec6e6ad69b4d791a8a9408410f3b

    commit 33c09045b0f86fcaa4619cbd679b47a074f71231
    Author: Andreas Huber <andih@google.com>
    Date:   Thu Feb 21 15:54:01 2013 -0800

        Render frames according to their timestamps.

        Change-Id: I8143a95cffe775799d6a4bb093558bd7abb1f063

    commit d8b6daae2160bf1c016d7c6251256b46bb89db42
    Author: Andreas Huber <andih@google.com>
    Date:   Thu Feb 21 15:01:27 2013 -0800

        Better packet-lost logic.

        Change-Id: I611eee5a42bd089638cf45b0e16f628ff2a955ab

    commit 782c6b15717e2d062d96665a089d06c0577733d0
    Author: Andreas Huber <andih@google.com>
    Date:   Wed Feb 20 15:06:47 2013 -0800

        Add a dedicated looper for the MediaReceiver

        Change-Id: I3b79cad367fb69c9a160a8d009af8c5f5142b98e

    commit 4c7b8b10861674b773270103bcabd1a99486a691
    Author: Andreas Huber <andih@google.com>
    Date:   Wed Feb 20 14:30:28 2013 -0800

        Tweaks to RTPSender and RTPReceiver

        Change-Id: Ib535552f289a26cfead6df8c63e4c63d3987d4e9

    commit 39226b28177a816cda5c67b321745d396b18277d
    Author: Andreas Huber <andih@google.com>
    Date:   Tue Feb 19 08:48:25 2013 -0800

        Playing around with non muxed delivery

        Change-Id: I845375f6938d04bc30502840c2ceb7688dc9b237

    commit c16d21de75d8ecdbcd9abce14934afe484970061
    Author: Andreas Huber <andih@google.com>
    Date:   Wed Feb 13 14:43:35 2013 -0800

        A more solid base for RTP communication.

        Change-Id: I52033eeb0feba0ff029d61553a821c82f2fa1c3f

    Change-Id: I57e3bcfc1c59a012b15aaaa42ed81f09c34c26bb

Change-Id: I4b09db4a44d0eeded7a1658f6dc6c97d4b8be720
parent d573622d
Loading
Loading
Loading
Loading
+12 −0
Original line number Original line Diff line number Diff line
@@ -23,6 +23,7 @@


#include <arpa/inet.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <fcntl.h>
#include <linux/tcp.h>
#include <net/if.h>
#include <net/if.h>
#include <netdb.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/in.h>
@@ -314,6 +315,9 @@ status_t ANetworkSession::Session::readMore() {
            sp<ABuffer> packet = new ABuffer(packetSize);
            sp<ABuffer> packet = new ABuffer(packetSize);
            memcpy(packet->data(), mInBuffer.c_str() + 2, packetSize);
            memcpy(packet->data(), mInBuffer.c_str() + 2, packetSize);


            int64_t nowUs = ALooper::GetNowUs();
            packet->meta()->setInt64("arrivalTimeUs", nowUs);

            sp<AMessage> notify = mNotify->dup();
            sp<AMessage> notify = mNotify->dup();
            notify->setInt32("sessionID", mSessionID);
            notify->setInt32("sessionID", mSessionID);
            notify->setInt32("reason", kWhatDatagram);
            notify->setInt32("reason", kWhatDatagram);
@@ -766,6 +770,14 @@ status_t ANetworkSession::createClientOrServer(


        res = setsockopt(s, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
        res = setsockopt(s, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));


        if (res < 0) {
            err = -errno;
            goto bail2;
        }
    } else if (mode == kModeCreateTCPDatagramSessionActive) {
        int flag = 1;
        res = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));

        if (res < 0) {
        if (res < 0) {
            err = -errno;
            err = -errno;
            goto bail2;
            goto bail2;
+28 −4
Original line number Original line Diff line number Diff line
@@ -4,21 +4,23 @@ include $(CLEAR_VARS)


LOCAL_SRC_FILES:= \
LOCAL_SRC_FILES:= \
        ANetworkSession.cpp             \
        ANetworkSession.cpp             \
        MediaReceiver.cpp               \
        MediaSender.cpp                 \
        Parameters.cpp                  \
        Parameters.cpp                  \
        ParsedMessage.cpp               \
        ParsedMessage.cpp               \
        rtp/RTPAssembler.cpp            \
        rtp/RTPReceiver.cpp             \
        rtp/RTPSender.cpp               \
        sink/DirectRenderer.cpp         \
        sink/DirectRenderer.cpp         \
        sink/LinearRegression.cpp       \
        sink/RTPSink.cpp                \
        sink/TunnelRenderer.cpp         \
        sink/TunnelRenderer.cpp         \
        sink/WifiDisplaySink.cpp        \
        sink/WifiDisplaySink.cpp        \
        SNTPClient.cpp                  \
        source/Converter.cpp            \
        source/Converter.cpp            \
        source/MediaPuller.cpp          \
        source/MediaPuller.cpp          \
        source/PlaybackSession.cpp      \
        source/PlaybackSession.cpp      \
        source/RepeaterSource.cpp       \
        source/RepeaterSource.cpp       \
        source/Sender.cpp               \
        source/TSPacketizer.cpp         \
        source/TSPacketizer.cpp         \
        source/WifiDisplaySource.cpp    \
        source/WifiDisplaySource.cpp    \
        TimeSeries.cpp                  \
        VideoFormats.cpp                \
        VideoFormats.cpp                \


LOCAL_C_INCLUDES:= \
LOCAL_C_INCLUDES:= \
@@ -85,3 +87,25 @@ LOCAL_MODULE:= udptest
LOCAL_MODULE_TAGS := debug
LOCAL_MODULE_TAGS := debug


include $(BUILD_EXECUTABLE)
include $(BUILD_EXECUTABLE)

################################################################################

include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \
        rtptest.cpp                 \

LOCAL_SHARED_LIBRARIES:= \
        libbinder                       \
        libgui                          \
        libmedia                        \
        libstagefright                  \
        libstagefright_foundation       \
        libstagefright_wfd              \
        libutils                        \

LOCAL_MODULE:= rtptest

LOCAL_MODULE_TAGS := debug

include $(BUILD_EXECUTABLE)
+311 −0
Original line number Original line Diff line number Diff line
/*
 * 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 transportMode,
        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(transportMode, 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);
            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();
}

}  // namespace android

+108 −0
Original line number Original line Diff line number Diff line
/*
 * 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 transportMode,
            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);

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
+443 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading