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

Commit cc227036 authored by Lajos Molnar's avatar Lajos Molnar
Browse files

nuplayer: add widevine support to GenericSource

Bug: 15699665
Change-Id: Ided823bd0b1118bbabb288cf62d6389518f820a9
parent 3cb57616
Loading
Loading
Loading
Loading
+67 −10
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <media/stagefright/MediaExtractor.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>
#include "../../libstagefright/include/WVMExtractor.h"

namespace android {

@@ -35,10 +36,16 @@ NuPlayer::GenericSource::GenericSource(
        const sp<AMessage> &notify,
        const sp<IMediaHTTPService> &httpService,
        const char *url,
        const KeyedVector<String8, String8> *headers)
        const KeyedVector<String8, String8> *headers,
        bool isWidevine,
        bool uidValid,
        uid_t uid)
    : Source(notify),
      mDurationUs(0ll),
      mAudioIsVorbis(false) {
      mAudioIsVorbis(false),
      mIsWidevine(isWidevine),
      mUIDValid(uidValid),
      mUID(uid) {
    DataSource::RegisterDefaultSniffers();

    sp<DataSource> dataSource =
@@ -63,7 +70,31 @@ NuPlayer::GenericSource::GenericSource(

void NuPlayer::GenericSource::initFromDataSource(
        const sp<DataSource> &dataSource) {
    sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
    sp<MediaExtractor> extractor;

    if (mIsWidevine) {
        String8 mimeType;
        float confidence;
        sp<AMessage> dummy;
        bool success;

        success = SniffWVM(dataSource, &mimeType, &confidence, &dummy);
        if (!success
                || strcasecmp(
                    mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) {
            ALOGE("unsupported widevine mime: %s", mimeType.string());
            return;
        }

        sp<WVMExtractor> wvmExtractor = new WVMExtractor(dataSource);
        wvmExtractor->setAdaptiveStreamingMode(true);
        if (mUIDValid) {
            wvmExtractor->setUID(mUID);
        }
        extractor = wvmExtractor;
    } else {
        extractor = MediaExtractor::Create(dataSource);
    }

    CHECK(extractor != NULL);

@@ -113,6 +144,13 @@ void NuPlayer::GenericSource::initFromDataSource(
    }
}

status_t NuPlayer::GenericSource::setBuffers(bool audio, Vector<MediaBuffer *> &buffers) {
    if (mIsWidevine && !audio) {
        return mVideoTrack.mSource->setBuffers(buffers);
    }
    return INVALID_OPERATION;
}

NuPlayer::GenericSource::~GenericSource() {
}

@@ -128,7 +166,8 @@ void NuPlayer::GenericSource::prepareAsync() {
    }

    notifyFlagsChanged(
            FLAG_CAN_PAUSE
            (mIsWidevine ? FLAG_SECURE : 0)
            | FLAG_CAN_PAUSE
            | FLAG_CAN_SEEK_BACKWARD
            | FLAG_CAN_SEEK_FORWARD
            | FLAG_CAN_SEEK);
@@ -180,9 +219,14 @@ status_t NuPlayer::GenericSource::dequeueAccessUnit(
        return -EWOULDBLOCK;
    }

    if (mIsWidevine && !audio) {
        // try to read a buffer as we may not have been able to the last time
        readBuffer(audio, -1ll);
    }

    status_t finalResult;
    if (!track->mPackets->hasBufferAvailable(&finalResult)) {
        return finalResult == OK ? -EWOULDBLOCK : finalResult;
        return (finalResult == OK ? -EWOULDBLOCK : finalResult);
    }

    status_t result = track->mPackets->dequeueAccessUnit(accessUnit);
@@ -280,6 +324,10 @@ void NuPlayer::GenericSource::readBuffer(
        seeking = true;
    }

    if (mIsWidevine && !audio) {
        options.setNonBlocking();
    }

    for (;;) {
        MediaBuffer *mbuf;
        status_t err = track->mSource->read(&mbuf, &options);
@@ -293,11 +341,18 @@ void NuPlayer::GenericSource::readBuffer(
                outLength += sizeof(int32_t);
            }

            sp<ABuffer> buffer = new ABuffer(outLength);

            sp<ABuffer> buffer;
            if (mIsWidevine && !audio) {
                // data is already provided in the buffer
                buffer = new ABuffer(NULL, mbuf->range_length());
                buffer->meta()->setPointer("mediaBuffer", mbuf);
                mbuf->add_ref();
            } else {
                buffer = new ABuffer(outLength);
                memcpy(buffer->data(),
                       (const uint8_t *)mbuf->data() + mbuf->range_offset(),
                       mbuf->range_length());
            }

            if (audio && mAudioIsVorbis) {
                int32_t numPageSamples;
@@ -332,6 +387,8 @@ void NuPlayer::GenericSource::readBuffer(

            track->mPackets->queueAccessUnit(buffer);
            break;
        } else if (err == WOULD_BLOCK) {
            break;
        } else if (err == INFO_FORMAT_CHANGED) {
#if 0
            track->mPackets->queueDiscontinuity(
+9 −1
Original line number Diff line number Diff line
@@ -35,7 +35,10 @@ struct NuPlayer::GenericSource : public NuPlayer::Source {
            const sp<AMessage> &notify,
            const sp<IMediaHTTPService> &httpService,
            const char *url,
            const KeyedVector<String8, String8> *headers);
            const KeyedVector<String8, String8> *headers,
            bool isWidevine = false,
            bool uidValid = false,
            uid_t uid = 0);

    GenericSource(
            const sp<AMessage> &notify,
@@ -54,6 +57,8 @@ struct NuPlayer::GenericSource : public NuPlayer::Source {
    virtual sp<AMessage> getTrackInfo(size_t trackIndex) const;
    virtual status_t seekTo(int64_t seekTimeUs);

    virtual status_t setBuffers(bool audio, Vector<MediaBuffer *> &buffers);

protected:
    virtual ~GenericSource();

@@ -73,6 +78,9 @@ private:

    int64_t mDurationUs;
    bool mAudioIsVorbis;
    bool mIsWidevine;
    bool mUIDValid;
    uid_t mUID;

    void initFromDataSource(const sp<DataSource> &dataSource);

+8 −0
Original line number Diff line number Diff line
@@ -21,11 +21,14 @@
#include "NuPlayer.h"

#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/MetaData.h>
#include <utils/Vector.h>

namespace android {

struct ABuffer;
struct MetaData;
struct MediaBuffer;

struct NuPlayer::Source : public AHandler {
    enum Flags {
@@ -34,6 +37,7 @@ struct NuPlayer::Source : public AHandler {
        FLAG_CAN_SEEK_FORWARD   = 4,  // the "10 sec forward button"
        FLAG_CAN_SEEK           = 8,  // the "seek bar"
        FLAG_DYNAMIC_DURATION   = 16,
        FLAG_SECURE             = 32,
    };

    enum {
@@ -89,6 +93,10 @@ struct NuPlayer::Source : public AHandler {
        return INVALID_OPERATION;
    }

    virtual status_t setBuffers(bool /* audio */, Vector<MediaBuffer *> &/* buffers */) {
        return INVALID_OPERATION;
    }

    virtual bool isRealTime() const {
        return false;
    }