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

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

Various tweaks to wfd

related-to-bug: 7426218

Squashed commit of the following:

commit 1553f1a1c66af998674168f7f7a3be23fcb0c794
Author: Andreas Huber <andih@google.com>
Date:   Tue Oct 30 15:51:27 2012 -0700

    Add LPCM, AVC and AVC HRD descriptors as necessary.

    Change-Id: Ibc836fced0fe37e8a25574c2295e886765b9ea6f

commit 4e74db61d2d31ebe239acbdec8f110f88016a4ea
Author: Andreas Huber <andih@google.com>
Date:   Tue Oct 30 15:50:52 2012 -0700

    added copyright headers to Sender.{cpp,h}

    Change-Id: If615ccb8767e32bd83ed1f0f669acc39a72489f6

commit 7144bf8ae68c5cdb8faa6e219547aabbd750f04e
Author: Andreas Huber <andih@google.com>
Date:   Tue Oct 30 15:50:25 2012 -0700

    Reenable suspension of the RepeaterSource

    Change-Id: I765338fcde89c65e4b69be45a5949eba6bcdcf6f

commit 812164bcfa0699821d7d8eefcc0dff96b2e2cd08
Author: Andreas Huber <andih@google.com>
Date:   Tue Oct 30 14:03:50 2012 -0700

    Add 2 stuffing bytes to the PES headers for audio tracks.

    Change-Id: I8b9c634f6a565ab7fa7ecdb610f7d8557e0b139b

commit a084a741a63015d47c92d99fcd8b980fe615dc7d
Author: Andreas Huber <andih@google.com>
Date:   Tue Oct 30 13:19:38 2012 -0700

    Fix PCM audio packetization in WFD.

    Change-Id: I99a435f9fe6b4397f24d6c22afae5ae2505ffc14

commit c5cb9369585f701f34bce41534940d5f9b59248f
Author: Andreas Huber <andih@google.com>
Date:   Tue Oct 30 13:19:12 2012 -0700

    Support extraction of PCM audio from transport streams.

    Change-Id: I28a0516756ebcb5587325b6588df013ac871ffb9

commit b0a0512300ae037d6b39c2d04952d34b5fc12b2d
Author: Andreas Huber <andih@google.com>
Date:   Tue Oct 30 08:54:13 2012 -0700

    disable suspend of the RepeaterSource

    Change-Id: Ibf42a98185b0567f817ae582a82e6580f95d3d40

commit 4330e8b7668dc92a6d882b5622c0697cf292d04c
Author: Andreas Huber <andih@google.com>
Date:   Mon Oct 29 14:11:25 2012 -0700

    Better handling of datagrams in ANetworkSession

    reduce unnecessary copy overhead.

    Change-Id: I2ed8c767274ba07764f03e8d4913041168e5755f

commit a44e73c322ba3f2c336f7cc4e1d63d3a74faa75d
Author: Andreas Huber <andih@google.com>
Date:   Mon Oct 29 11:14:47 2012 -0700

    Network traffic is now handled on a separate thread.

    Audio and video are queued to ensure proper A/V interleaving.
    Scheduled packet sends according to capture timestamps to reduce
    send-jitter.

    Change-Id: Ibd6357c1e663086cf87bec0a98f8e54dfdfaa0e5
    related-to-bug: 7426218

Change-Id: Ia440129d656c35814abf18df06da50b73d5bb554
parent cc37e71d
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -131,6 +131,8 @@ private:
    sp<AnotherPacketSource> mSource;
    bool mPayloadStarted;

    uint64_t mPrevPTS;

    ElementaryStreamQueue *mQueue;

    status_t flush();
@@ -458,6 +460,7 @@ ATSParser::Stream::Stream(
      mPCR_PID(PCR_PID),
      mExpectedContinuityCounter(-1),
      mPayloadStarted(false),
      mPrevPTS(0),
      mQueue(NULL) {
    switch (mStreamType) {
        case STREAMTYPE_H264:
@@ -486,6 +489,11 @@ ATSParser::Stream::Stream(
                    ElementaryStreamQueue::MPEG4_VIDEO);
            break;

        case STREAMTYPE_PCM_AUDIO:
            mQueue = new ElementaryStreamQueue(
                    ElementaryStreamQueue::PCM_AUDIO);
            break;

        default:
            break;
    }
@@ -583,6 +591,7 @@ bool ATSParser::Stream::isAudio() const {
        case STREAMTYPE_MPEG1_AUDIO:
        case STREAMTYPE_MPEG2_AUDIO:
        case STREAMTYPE_MPEG2_AUDIO_ADTS:
        case STREAMTYPE_PCM_AUDIO:
            return true;

        default:
@@ -827,6 +836,14 @@ status_t ATSParser::Stream::flush() {
void ATSParser::Stream::onPayloadData(
        unsigned PTS_DTS_flags, uint64_t PTS, uint64_t DTS,
        const uint8_t *data, size_t size) {
#if 0
    ALOGI("payload streamType 0x%02x, PTS = 0x%016llx, dPTS = %lld",
          mStreamType,
          PTS,
          (int64_t)PTS - mPrevPTS);
    mPrevPTS = PTS;
#endif

    ALOGV("onPayloadData mStreamType=0x%02x", mStreamType);

    int64_t timeUs = 0ll;  // no presentation timestamp available.
+1 −0
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ struct ATSParser : public RefBase {
        STREAMTYPE_MPEG2_AUDIO_ADTS     = 0x0f,
        STREAMTYPE_MPEG4_VIDEO          = 0x10,
        STREAMTYPE_H264                 = 0x1b,
        STREAMTYPE_PCM_AUDIO            = 0x83,
    };

protected:
+63 −0
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@

#include "include/avc_utils.h"

#include <netinet/in.h>

namespace android {

ElementaryStreamQueue::ElementaryStreamQueue(Mode mode, uint32_t flags)
@@ -248,6 +250,11 @@ status_t ElementaryStreamQueue::appendData(
                break;
            }

            case PCM_AUDIO:
            {
                break;
            }

            default:
                TRESPASS();
                break;
@@ -324,12 +331,68 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnit() {
            return dequeueAccessUnitMPEGVideo();
        case MPEG4_VIDEO:
            return dequeueAccessUnitMPEG4Video();
        case PCM_AUDIO:
            return dequeueAccessUnitPCMAudio();
        default:
            CHECK_EQ((unsigned)mMode, (unsigned)MPEG_AUDIO);
            return dequeueAccessUnitMPEGAudio();
    }
}

sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitPCMAudio() {
    if (mBuffer->size() < 4) {
        return NULL;
    }

    ABitReader bits(mBuffer->data(), 4);
    CHECK_EQ(bits.getBits(8), 0xa0);
    unsigned numAUs = bits.getBits(8);
    bits.skipBits(8);
    unsigned quantization_word_length = bits.getBits(2);
    unsigned audio_sampling_frequency = bits.getBits(3);
    unsigned num_channels = bits.getBits(3);

    CHECK_EQ(audio_sampling_frequency, 2);  // 48kHz
    CHECK_EQ(num_channels, 1u);  // stereo!

    if (mFormat == NULL) {
        mFormat = new MetaData;
        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
        mFormat->setInt32(kKeyChannelCount, 2);
        mFormat->setInt32(kKeySampleRate, 48000);
    }

    static const size_t kFramesPerAU = 80;
    size_t frameSize = 2 /* numChannels */ * sizeof(int16_t);

    size_t payloadSize = numAUs * frameSize * kFramesPerAU;

    if (mBuffer->size() < 4 + payloadSize) {
        return NULL;
    }

    sp<ABuffer> accessUnit = new ABuffer(payloadSize);
    memcpy(accessUnit->data(), mBuffer->data() + 4, payloadSize);

    int64_t timeUs = fetchTimestamp(payloadSize + 4);
    CHECK_GE(timeUs, 0ll);
    accessUnit->meta()->setInt64("timeUs", timeUs);

    int16_t *ptr = (int16_t *)accessUnit->data();
    for (size_t i = 0; i < payloadSize / sizeof(int16_t); ++i) {
        ptr[i] = ntohs(ptr[i]);
    }

    memmove(
            mBuffer->data(),
            mBuffer->data() + 4 + payloadSize,
            mBuffer->size() - 4 - payloadSize);

    mBuffer->setRange(0, mBuffer->size() - 4 - payloadSize);

    return accessUnit;
}

sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitAAC() {
    int64_t timeUs;

+2 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ struct ElementaryStreamQueue {
        MPEG_AUDIO,
        MPEG_VIDEO,
        MPEG4_VIDEO,
        PCM_AUDIO,
    };

    enum Flags {
@@ -69,6 +70,7 @@ private:
    sp<ABuffer> dequeueAccessUnitMPEGAudio();
    sp<ABuffer> dequeueAccessUnitMPEGVideo();
    sp<ABuffer> dequeueAccessUnitMPEG4Video();
    sp<ABuffer> dequeueAccessUnitPCMAudio();

    // consume a logical (compressed) access unit of size "size",
    // returns its timestamp in us (or -1 if no time information).
+21 −16
Original line number Diff line number Diff line
@@ -94,8 +94,11 @@ private:
    sp<AMessage> mNotify;
    bool mSawReceiveFailure, mSawSendFailure;

    // for TCP / stream data
    AString mOutBuffer;
    List<size_t> mOutBufferSizes;

    // for UDP / datagrams
    List<sp<ABuffer> > mOutDatagrams;

    AString mInBuffer;

@@ -213,8 +216,8 @@ bool ANetworkSession::Session::wantsToRead() {
bool ANetworkSession::Session::wantsToWrite() {
    return !mSawSendFailure
        && (mState == CONNECTING
            || ((mState == CONNECTED || mState == DATAGRAM)
                    && !mOutBuffer.empty()));
            || (mState == CONNECTED && !mOutBuffer.empty())
            || (mState == DATAGRAM && !mOutDatagrams.empty()));
}

status_t ANetworkSession::Session::readMore() {
@@ -398,30 +401,27 @@ status_t ANetworkSession::Session::readMore() {

status_t ANetworkSession::Session::writeMore() {
    if (mState == DATAGRAM) {
        CHECK(!mOutBufferSizes.empty());
        CHECK(!mOutDatagrams.empty());

        status_t err;
        do {
            size_t size = *mOutBufferSizes.begin();

            CHECK_GE(mOutBuffer.size(), size);
            const sp<ABuffer> &datagram = *mOutDatagrams.begin();

            int n;
            do {
                n = send(mSocket, mOutBuffer.c_str(), size, 0);
                n = send(mSocket, datagram->data(), datagram->size(), 0);
            } while (n < 0 && errno == EINTR);

            err = OK;

            if (n > 0) {
                mOutBufferSizes.erase(mOutBufferSizes.begin());
                mOutBuffer.erase(0, n);
                mOutDatagrams.erase(mOutDatagrams.begin());
            } else if (n < 0) {
                err = -errno;
            } else if (n == 0) {
                err = -ECONNRESET;
            }
        } while (err == OK && !mOutBufferSizes.empty());
        } while (err == OK && !mOutDatagrams.empty());

        if (err == -EAGAIN) {
            err = OK;
@@ -488,6 +488,16 @@ status_t ANetworkSession::Session::writeMore() {
status_t ANetworkSession::Session::sendRequest(const void *data, ssize_t size) {
    CHECK(mState == CONNECTED || mState == DATAGRAM);

    if (mState == DATAGRAM) {
        CHECK_GE(size, 0);

        sp<ABuffer> datagram = new ABuffer(size);
        memcpy(datagram->data(), data, size);

        mOutDatagrams.push_back(datagram);
        return OK;
    }

    if (mState == CONNECTED && !mIsRTSPConnection) {
        CHECK_LE(size, 65535);

@@ -502,11 +512,6 @@ status_t ANetworkSession::Session::sendRequest(const void *data, ssize_t size) {
            (const char *)data,
            (size >= 0) ? size : strlen((const char *)data));

    if (mState == DATAGRAM) {
        CHECK_GE(size, 0);
        mOutBufferSizes.push_back(size);
    }

    return OK;
}

Loading