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

Commit 83d9698c authored by Wei Jia's avatar Wei Jia Committed by gitbuildkicker
Browse files

MediaExtractor: add DrmInitialization in IDataSource.

Bug: 28901867
Change-Id: Ic33dc8dc2f5f36239e057d2f2aceeb7738eef968
(cherry picked from commit 2a5e49c9)
parent 24d9928c
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
namespace android {

class IMemory;
class DecryptHandle;

// A binder interface for implementing a stagefright DataSource remotely.
class IDataSource : public IInterface {
@@ -47,6 +48,8 @@ public:
    virtual uint32_t getFlags() = 0;
    // get a description of the source, e.g. the url or filename it is based on
    virtual String8 toString() = 0;
    // Initialize DRM and return a DecryptHandle.
    virtual sp<DecryptHandle> DrmInitialization(const char *mime) = 0;

private:
    DISALLOW_EVIL_CONSTRUCTORS(IDataSource);
+79 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@

#include <binder/IMemory.h>
#include <binder/Parcel.h>
#include <drm/drm_framework_common.h>
#include <media/stagefright/foundation/ADebug.h>

namespace android {
@@ -34,6 +35,7 @@ enum {
    CLOSE,
    GET_FLAGS,
    TO_STRING,
    DRM_INITIALIZATION,
};

struct BpDataSource : public BpInterface<IDataSource> {
@@ -84,6 +86,47 @@ struct BpDataSource : public BpInterface<IDataSource> {
        remote()->transact(TO_STRING, data, &reply);
        return reply.readString8();
    }

    virtual sp<DecryptHandle> DrmInitialization(const char *mime) {
        Parcel data, reply;
        data.writeInterfaceToken(IDataSource::getInterfaceDescriptor());
        if (mime == NULL) {
            data.writeInt32(0);
        } else {
            data.writeInt32(1);
            data.writeCString(mime);
        }
        remote()->transact(DRM_INITIALIZATION, data, &reply);
        sp<DecryptHandle> handle;
        if (reply.dataAvail() != 0) {
            handle = new DecryptHandle();
            handle->decryptId = reply.readInt32();
            handle->mimeType = reply.readString8();
            handle->decryptApiType = reply.readInt32();
            handle->status = reply.readInt32();

            const int bufferLength = data.readInt32();
            if (bufferLength != -1) {
                handle->decryptInfo = new DecryptInfo();
                handle->decryptInfo->decryptBufferLength = bufferLength;
            }

            size_t size = data.readInt32();
            for (size_t i = 0; i < size; ++i) {
                DrmCopyControl key = (DrmCopyControl)data.readInt32();
                int value = data.readInt32();
                handle->copyControlVector.add(key, value);
            }

            size = data.readInt32();
            for (size_t i = 0; i < size; ++i) {
                String8 key = data.readString8();
                String8 value = data.readString8();
                handle->extendedData.add(key, value);
            }
        }
        return handle;
    }
};

IMPLEMENT_META_INTERFACE(DataSource, "android.media.IDataSource");
@@ -126,6 +169,42 @@ status_t BnDataSource::onTransact(
            reply->writeString8(toString());
            return NO_ERROR;
        } break;
        case DRM_INITIALIZATION: {
            CHECK_INTERFACE(IDataSource, data, reply);
            const char *mime = NULL;
            const int32_t flag = data.readInt32();
            if (flag != 0) {
                mime = data.readCString();
            }
            sp<DecryptHandle> handle = DrmInitialization(mime);
            if (handle != NULL) {
                reply->writeInt32(handle->decryptId);
                reply->writeString8(handle->mimeType);
                reply->writeInt32(handle->decryptApiType);
                reply->writeInt32(handle->status);

                if (handle->decryptInfo != NULL) {
                    reply->writeInt32(handle->decryptInfo->decryptBufferLength);
                } else {
                    reply->writeInt32(-1);
                }

                size_t size = handle->copyControlVector.size();
                reply->writeInt32(size);
                for (size_t i = 0; i < size; ++i) {
                    reply->writeInt32(handle->copyControlVector.keyAt(i));
                    reply->writeInt32(handle->copyControlVector.valueAt(i));
                }

                size = handle->extendedData.size();
                reply->writeInt32(size);
                for (size_t i = 0; i < size; ++i) {
                    reply->writeString8(handle->extendedData.keyAt(i));
                    reply->writeString8(handle->extendedData.valueAt(i));
                }
            }
            return NO_ERROR;
        } break;

        default:
            return BBinder::onTransact(code, data, reply, flags);
+8 −2
Original line number Diff line number Diff line
@@ -100,7 +100,10 @@ static size_t getFrameSize(bool isWide, unsigned FT) {
static status_t getFrameSizeByOffset(const sp<DataSource> &source,
        off64_t offset, bool isWide, size_t *frameSize) {
    uint8_t header;
    if (source->readAt(offset, &header, 1) < 1) {
    ssize_t count = source->readAt(offset, &header, 1);
    if (count == 0) {
        return ERROR_END_OF_STREAM;
    } else if (count < 0) {
        return ERROR_IO;
    }

@@ -140,7 +143,10 @@ AMRExtractor::AMRExtractor(const sp<DataSource> &source)

    if (mDataSource->getSize(&streamSize) == OK) {
         while (offset < streamSize) {
            if (getFrameSizeByOffset(source, offset, mIsWide, &frameSize) != OK) {
             status_t status = getFrameSizeByOffset(source, offset, mIsWide, &frameSize);
             if (status == ERROR_END_OF_STREAM) {
                 break;
             } else if (status != OK) {
                return;
            }

+18 −0
Original line number Diff line number Diff line
@@ -109,6 +109,10 @@ void CallbackDataSource::close() {
    }
}

sp<DecryptHandle> CallbackDataSource::DrmInitialization(const char *mime) {
    return mIDataSource->DrmInitialization(mime);
}

TinyCacheSource::TinyCacheSource(const sp<DataSource>& source)
    : mSource(source), mCachedOffset(0), mCachedSize(0) {
    mName = String8::format("TinyCacheSource(%s)", mSource->toString().string());
@@ -146,12 +150,19 @@ ssize_t TinyCacheSource::readAt(off64_t offset, void* data, size_t size) {
        }
    }


    // Fill the cache and copy to the caller.
    const ssize_t numRead = mSource->readAt(offset, mCache, kCacheSize);
    if (numRead <= 0) {
        // Flush cache on error
        mCachedSize = 0;
        mCachedOffset = 0;
        return numRead;
    }
    if ((size_t)numRead > kCacheSize) {
        // Flush cache on error
        mCachedSize = 0;
        mCachedOffset = 0;
        return ERROR_OUT_OF_RANGE;
    }

@@ -172,4 +183,11 @@ uint32_t TinyCacheSource::flags() {
    return mSource->flags();
}

sp<DecryptHandle> TinyCacheSource::DrmInitialization(const char *mime) {
    // flush cache when DrmInitialization occurs since decrypted
    // data may differ from what is in cache.
    mCachedOffset = 0;
    mCachedSize = 0;
    return mSource->DrmInitialization(mime);
}
} // namespace android
+5 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ public:
    virtual void close();
    virtual uint32_t getFlags();
    virtual String8 toString();
    virtual sp<DecryptHandle> DrmInitialization(const char *mime);

private:
    sp<IMemory> mMemory;
@@ -134,6 +135,10 @@ String8 RemoteDataSource::toString() {
    return mName;
}

sp<DecryptHandle> RemoteDataSource::DrmInitialization(const char *mime) {
    return mSource->DrmInitialization(mime);
}

// static
sp<IMediaExtractor> MediaExtractor::Create(
        const sp<DataSource> &source, const char *mime) {
Loading