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

Commit 507c191a authored by Wei Jia's avatar Wei Jia Committed by android-build-merger
Browse files

Merge "IMediaSource: add readMultiple API to speed up inter-process reading." into nyc-dev

am: 51f03edc

* commit '51f03edc':
  IMediaSource: add readMultiple API to speed up inter-process reading.

Change-Id: I3882ea39ef22a8c2e9fafbf734854c6e3ca931b7
parents 5fa6231e 51f03edc
Loading
Loading
Loading
Loading
+23 −1
Original line number Diff line number Diff line
@@ -32,6 +32,11 @@ class IMediaSource : public IInterface {
public:
    DECLARE_META_INTERFACE(MediaSource);

    enum {
        // Maximum number of buffers would be read in readMultiple.
        kMaxNumReadMultiple = 128,
    };

    // To be called before any other methods on this object, except
    // getFormat().
    virtual status_t start(MetaData *params = NULL) = 0;
@@ -87,7 +92,7 @@ public:
    };

    // Returns a new buffer of data. Call blocks until a
    // buffer is available, an error is encountered of the end of the stream
    // buffer is available, an error is encountered or the end of the stream
    // is reached.
    // End of stream is signalled by a result of ERROR_END_OF_STREAM.
    // A result of INFO_FORMAT_CHANGED indicates that the format of this
@@ -96,6 +101,19 @@ public:
    virtual status_t read(
            MediaBuffer **buffer, const ReadOptions *options = NULL) = 0;

    // Returns a vector of new buffers of data. The vector size could be
    // <= |maxNumBuffers|. Used for buffers with small size
    // since all buffer data are passed back by binder, not shared memory.
    // Call blocks until an error is encountered, or the end of the stream is
    // reached, or format change is hit, or |kMaxNumReadMultiple| buffers have
    // been read.
    // End of stream is signalled by a result of ERROR_END_OF_STREAM.
    // A result of INFO_FORMAT_CHANGED indicates that the format of this
    // MediaSource has changed mid-stream, the client can continue reading
    // but should be prepared for buffers of the new configuration.
    virtual status_t readMultiple(
            Vector<MediaBuffer *> *buffers, uint32_t maxNumBuffers = 1) = 0;

    // Causes this source to suspend pulling data from its upstream source
    // until a subsequent read-with-seek. Currently only supported by
    // OMXCodec.
@@ -126,6 +144,10 @@ public:
        return ERROR_UNSUPPORTED;
    }

    virtual status_t readMultiple(
            Vector<MediaBuffer *> * /* buffers */, uint32_t /* maxNumBuffers = 1 */) {
        return ERROR_UNSUPPORTED;
    }
protected:
    virtual ~BnMediaSource();

+63 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ enum {
    PAUSE,
    GETFORMAT,
    READ,
    READMULTIPLE,
    RELEASE_BUFFER
};

@@ -189,6 +190,37 @@ public:
        return ret;
    }

    virtual status_t readMultiple(Vector<MediaBuffer *> *buffers, uint32_t maxNumBuffers) {
        ALOGV("readMultiple");
        if (buffers == NULL || !buffers->isEmpty()) {
            return BAD_VALUE;
        }
        Parcel data, reply;
        data.writeInterfaceToken(BpMediaSource::getInterfaceDescriptor());
        data.writeUint32(maxNumBuffers);
        status_t ret = remote()->transact(READMULTIPLE, data, &reply);
        if (ret != NO_ERROR) {
            return ret;
        }
        // wrap the returned data in a vector of MediaBuffers
        int32_t bufCount = 0;
        while (1) {
            if (reply.readInt32() == 0) {
                break;
            }
            int32_t len = reply.readInt32();
            ALOGV("got len %d", len);
            MediaBuffer *buf = new MediaBuffer(len);
            reply.read(buf->data(), len);
            buf->meta_data()->updateFromParcel(reply);
            buffers->push_back(buf);
            ++bufCount;
        }
        ret = reply.readInt32();
        ALOGV("got status %d, bufCount %d", ret, bufCount);
        return ret;
    }

    virtual status_t pause() {
        ALOGV("pause");
        Parcel data, reply;
@@ -340,6 +372,37 @@ status_t BnMediaSource::onTransact(
            }
            return NO_ERROR;
        }
        case READMULTIPLE: {
            ALOGV("readmultiple");
            CHECK_INTERFACE(IMediaSource, data, reply);
            uint32_t maxNumBuffers;
            data.readUint32(&maxNumBuffers);
            status_t ret = NO_ERROR;
            uint32_t bufferCount = 0;
            if (maxNumBuffers > kMaxNumReadMultiple) {
                maxNumBuffers = kMaxNumReadMultiple;
            }
            while (bufferCount < maxNumBuffers) {
                if (reply->dataSize() >= MediaBuffer::kSharedMemThreshold) {
                    break;
                }

                MediaBuffer *buf = NULL;
                ret = read(&buf, NULL);
                if (ret != NO_ERROR || buf == NULL) {
                    break;
                }
                ++bufferCount;
                reply->writeInt32(1);  // indicate one more MediaBuffer.
                reply->writeByteArray(
                        buf->range_length(), (uint8_t*)buf->data() + buf->range_offset());
                buf->meta_data()->writeToParcel(*reply);
                buf->release();
            }
            reply->writeInt32(0);  // indicate no more MediaBuffer.
            reply->writeInt32(ret);
            return NO_ERROR;
        }
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
+28 −5
Original line number Diff line number Diff line
@@ -1420,14 +1420,28 @@ void NuPlayer::GenericSource::readBuffer(
        options.setNonBlocking();
    }

    bool couldReadMultiple = (!mIsWidevine && trackType == MEDIA_TRACK_TYPE_AUDIO);
    for (size_t numBuffers = 0; numBuffers < maxBuffers; ) {
        MediaBuffer *mbuf;
        status_t err = track->mSource->read(&mbuf, &options);
        Vector<MediaBuffer *> mediaBuffers;
        status_t err = NO_ERROR;

        if (!seeking && couldReadMultiple) {
            err = track->mSource->readMultiple(&mediaBuffers, (maxBuffers - numBuffers));
        } else {
            MediaBuffer *mbuf = NULL;
            err = track->mSource->read(&mbuf, &options);
            if (err == OK && mbuf != NULL) {
                mediaBuffers.push_back(mbuf);
            }
        }

        options.clearSeekTo();

        if (err == OK) {
        size_t id = 0;
        size_t count = mediaBuffers.size();
        for (; id < count; ++id) {
            int64_t timeUs;
            MediaBuffer *mbuf = mediaBuffers[id];
            if (!mbuf->meta_data()->findInt64(kKeyTime, &timeUs)) {
                mbuf->meta_data()->dumpToLog();
                track->mPackets->signalEOS(ERROR_MALFORMED);
@@ -1450,7 +1464,16 @@ void NuPlayer::GenericSource::readBuffer(
            formatChange = false;
            seeking = false;
            ++numBuffers;
        } else if (err == WOULD_BLOCK) {
        }
        if (id < count) {
            // Error, some mediaBuffer doesn't have kKeyTime.
            for (; id < count; ++id) {
                mediaBuffers[id]->release();
            }
            break;
        }

        if (err == WOULD_BLOCK) {
            break;
        } else if (err == INFO_FORMAT_CHANGED) {
#if 0
@@ -1459,7 +1482,7 @@ void NuPlayer::GenericSource::readBuffer(
                    NULL,
                    false /* discard */);
#endif
        } else {
        } else if (err != OK) {
            queueDiscontinuityIfNeeded(seeking, formatChange, trackType, track);
            track->mPackets->signalEOS(err);
            break;