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

Commit 2e829595 authored by Andreas Huber's avatar Andreas Huber Committed by Android (Google) Code Review
Browse files

Merge "Remove now obsolete implementation of streaming from AwesomePlayer."

parents 52185ff7 d936726f
Loading
Loading
Loading
Loading
+1 −249
Original line number Diff line number Diff line
@@ -33,8 +33,6 @@
#include "UDPPusher.h"

#include <binder/IPCThreadState.h>
#include <binder/MemoryDealer.h>
#include <media/IStreamSource.h>
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/AudioPlayer.h>
@@ -161,245 +159,6 @@ private:

////////////////////////////////////////////////////////////////////////////////

struct QueueDataSource;

struct QueueListener : public BnStreamListener {
    QueueListener(QueueDataSource *owner)
        : mOwner(owner) {
    }

    void clearOwner();

    virtual void queueBuffer(size_t index, size_t size);

    virtual void issueCommand(
            Command cmd, bool synchronous, const sp<AMessage> &msg);

private:
    Mutex mLock;

    QueueDataSource *mOwner;

    DISALLOW_EVIL_CONSTRUCTORS(QueueListener);
};

struct QueueDataSource : public DataSource {
    QueueDataSource(const sp<IStreamSource> &source);

    virtual status_t initCheck() const;

    virtual ssize_t readAt(off64_t offset, void *data, size_t size);

    virtual void queueBuffer(size_t index, size_t size);

    virtual void issueCommand(
            IStreamListener::Command cmd,
            bool synchronous,
            const sp<AMessage> &msg);

protected:
    virtual ~QueueDataSource();

private:
    enum {
        kNumBuffers = 16
    };

    struct QueueEntry {
        bool mIsCommand;

        IStreamListener::Command mCommand;
        sp<AMessage> mCommandMessage;

        size_t mIndex;
        size_t mOffset;
        size_t mSize;
    };

    Mutex mLock;
    Condition mCondition;

    sp<IStreamSource> mSource;
    sp<QueueListener> mListener;
    sp<MemoryDealer> mDealer;
    Vector<sp<IMemory> > mBuffers;

    List<QueueEntry> mQueue;

    off64_t mPosition;
    bool mEOS;

    DISALLOW_EVIL_CONSTRUCTORS(QueueDataSource);
};

QueueDataSource::QueueDataSource(const sp<IStreamSource> &source)
    : mSource(source),
      mPosition(0),
      mEOS(false) {
    mListener = new QueueListener(this);
    mSource->setListener(mListener);

    static const size_t kBufferSize = (8192 / 188) * 188;

    mDealer = new MemoryDealer(kNumBuffers * kBufferSize);
    for (size_t i = 0; i < kNumBuffers; ++i) {
        sp<IMemory> mem = mDealer->allocate(kBufferSize);
        CHECK(mem != NULL);

        mBuffers.push(mem);
    }
    mSource->setBuffers(mBuffers);

    for (size_t i = 0; i < kNumBuffers; ++i) {
        mSource->onBufferAvailable(i);
    }
}

QueueDataSource::~QueueDataSource() {
    Mutex::Autolock autoLock(mLock);

    mListener->clearOwner();
}

status_t QueueDataSource::initCheck() const {
    return OK;
}

ssize_t QueueDataSource::readAt(off64_t offset, void *data, size_t size) {
    if (offset != mPosition) {
        return -EPIPE;
    }

    Mutex::Autolock autoLock(mLock);

    if (mEOS) {
        return ERROR_END_OF_STREAM;
    }

    size_t sizeDone = 0;

    while (sizeDone < size) {
        while (mQueue.empty()) {
            mCondition.wait(mLock);
        }

        QueueEntry &entry = *mQueue.begin();

        if (entry.mIsCommand) {
            switch (entry.mCommand) {
                case IStreamListener::EOS:
                {
                    mEOS = true;

                    if (sizeDone > 0) {
                        offset += sizeDone;
                        return sizeDone;
                    } else {
                        return ERROR_END_OF_STREAM;
                    }
                    break;
                }

                case IStreamListener::DISCONTINUITY:
                {
                    CHECK_EQ(size, 188u);
                    CHECK_EQ(sizeDone, 0u);

                    memset(data, 0, size);
                    sizeDone = size;
                    break;
                }

                default:
                    break;
            }

            mQueue.erase(mQueue.begin());
            continue;
        }

        size_t copy = size - sizeDone;
        if (copy > entry.mSize) {
            copy = entry.mSize;
        }

        memcpy((uint8_t *)data + sizeDone,
               (const uint8_t *)mBuffers.itemAt(entry.mIndex)->pointer()
                    + entry.mOffset,
               copy);

        entry.mSize -= copy;
        entry.mOffset += copy;
        sizeDone += copy;

        if (entry.mSize == 0) {
            mSource->onBufferAvailable(entry.mIndex);
            mQueue.erase(mQueue.begin());
        }
    }

    mPosition += sizeDone;

    return sizeDone;
}

void QueueDataSource::queueBuffer(size_t index, size_t size) {
    Mutex::Autolock autoLock(mLock);

    CHECK_LT(index, mBuffers.size());
    CHECK_LE(size, mBuffers.itemAt(index)->size());

    QueueEntry entry;
    entry.mIsCommand = false;
    entry.mIndex = index;
    entry.mSize = size;
    entry.mOffset = 0;

    mQueue.push_back(entry);
    mCondition.signal();
}

void QueueDataSource::issueCommand(
        IStreamListener::Command cmd,
        bool synchronous,
        const sp<AMessage> &msg) {
    Mutex::Autolock autoLock(mLock);

    CHECK(!synchronous);

    QueueEntry entry;
    entry.mIsCommand = true;
    entry.mCommand = cmd;
    entry.mCommandMessage = msg;
    mQueue.push_back(entry);

    mCondition.signal();
}

void QueueListener::clearOwner() {
    Mutex::Autolock autoLock(mLock);
    mOwner = NULL;
}

void QueueListener::queueBuffer(size_t index, size_t size) {
    Mutex::Autolock autoLock(mLock);
    if (mOwner == NULL) {
        return;
    }
    mOwner->queueBuffer(index, size);
}

void QueueListener::issueCommand(
        Command cmd, bool synchronous, const sp<AMessage> &msg) {
    Mutex::Autolock autoLock(mLock);
    if (mOwner == NULL) {
        return;
    }
    mOwner->issueCommand(cmd, synchronous, msg);
}

////////////////////////////////////////////////////////////////////////////////

AwesomePlayer::AwesomePlayer()
    : mQueueStarted(false),
      mTimeSource(NULL),
@@ -511,14 +270,7 @@ status_t AwesomePlayer::setDataSource(
}

status_t AwesomePlayer::setDataSource(const sp<IStreamSource> &source) {
    Mutex::Autolock autoLock(mLock);

    reset_l();

    sp<DataSource> dataSource = new QueueDataSource(source);
    sp<MediaExtractor> extractor = new MPEG2TSExtractor(dataSource);

    return setDataSource_l(extractor);
    return INVALID_OPERATION;
}

status_t AwesomePlayer::setDataSource_l(