From dcd25efb46c41c8d24a0a9cf61fb57f84149709e Mon Sep 17 00:00:00 2001 From: Gloria Wang Date: Tue, 22 Jun 2010 13:55:38 -0700 Subject: DRM framework support: - add a sniffer for DRM files - add DRMSource and DRMExtractor for es_based DRM - add pread in FileSource.cpp for container_based DRM - add native DRM framework API calls in the player for DRM audio/video playback Change-Id: I4b9ef19165c9b4f44ff40eeededb9a665e78a90f --- media/libstagefright/FileSource.cpp | 90 +++++++++++++++++++++++++++++++++---- 1 file changed, 82 insertions(+), 8 deletions(-) (limited to 'media/libstagefright/FileSource.cpp') diff --git a/media/libstagefright/FileSource.cpp b/media/libstagefright/FileSource.cpp index b6f1af2..6b85048 100644 --- a/media/libstagefright/FileSource.cpp +++ b/media/libstagefright/FileSource.cpp @@ -21,14 +21,26 @@ namespace android { FileSource::FileSource(const char *filename) : mFile(fopen(filename, "rb")), + mFd(fileno(mFile)), mOffset(0), - mLength(-1) { + mLength(-1), + mDecryptHandle(NULL), + mDrmManagerClient(NULL), + mDrmBufOffset(0), + mDrmBufSize(0), + mDrmBuf(NULL){ } FileSource::FileSource(int fd, int64_t offset, int64_t length) : mFile(fdopen(fd, "rb")), + mFd(fd), mOffset(offset), - mLength(length) { + mLength(length), + mDecryptHandle(NULL), + mDrmManagerClient(NULL), + mDrmBufOffset(0), + mDrmBufSize(0), + mDrmBuf(NULL){ CHECK(offset >= 0); CHECK(length >= 0); } @@ -38,6 +50,14 @@ FileSource::~FileSource() { fclose(mFile); mFile = NULL; } + + if (mDrmBuf != NULL) { + delete[] mDrmBuf; + mDrmBuf = NULL; + } + if (mDecryptHandle != NULL) { + mDrmManagerClient->closeDecryptSession(mDecryptHandle); + } } status_t FileSource::initCheck() const { @@ -57,13 +77,18 @@ ssize_t FileSource::readAt(off_t offset, void *data, size_t size) { } } - int err = fseeko(mFile, offset + mOffset, SEEK_SET); - if (err < 0) { - LOGE("seek to %lld failed", offset + mOffset); - return UNKNOWN_ERROR; - } + if (mDecryptHandle != NULL && DecryptApiType::CONTAINER_BASED + == mDecryptHandle->decryptApiType) { + return readAtDRM(offset, data, size); + } else { + int err = fseeko(mFile, offset + mOffset, SEEK_SET); + if (err < 0) { + LOGE("seek to %lld failed", offset + mOffset); + return UNKNOWN_ERROR; + } - return fread(data, 1, size, mFile); + return fread(data, 1, size, mFile); + } } status_t FileSource::getSize(off_t *size) { @@ -79,4 +104,53 @@ status_t FileSource::getSize(off_t *size) { return OK; } +DecryptHandle* FileSource::DrmInitialization(DrmManagerClient* client) { + mDrmManagerClient = client; + if (mDecryptHandle == NULL) { + mDecryptHandle = mDrmManagerClient->openDecryptSession( + mFd, mOffset, mLength); + } + + if (mDecryptHandle == NULL) { + mDrmManagerClient = NULL; + } + + return mDecryptHandle; +} + +void FileSource::getDrmInfo(DecryptHandle **handle, DrmManagerClient **client) { + *handle = mDecryptHandle; + + *client = mDrmManagerClient; +} + +ssize_t FileSource::readAtDRM(off_t offset, void *data, size_t size) { + size_t DRM_CACHE_SIZE = 1024; + if (mDrmBuf == NULL) { + mDrmBuf = new unsigned char[DRM_CACHE_SIZE]; + } + + if (mDrmBuf != NULL && mDrmBufSize > 0 && (offset + mOffset) >= mDrmBufOffset + && (offset + mOffset + size) <= (mDrmBufOffset + mDrmBufSize)) { + /* Use buffered data */ + memcpy(data, (void*)(mDrmBuf+(offset+mOffset-mDrmBufOffset)), size); + return size; + } else if (size <= DRM_CACHE_SIZE) { + /* Buffer new data */ + mDrmBufOffset = offset + mOffset; + mDrmBufSize = mDrmManagerClient->pread(mDecryptHandle, mDrmBuf, + DRM_CACHE_SIZE, offset + mOffset); + if (mDrmBufSize > 0) { + int64_t dataRead = 0; + dataRead = size > mDrmBufSize ? mDrmBufSize : size; + memcpy(data, (void*)mDrmBuf, dataRead); + return dataRead; + } else { + return mDrmBufSize; + } + } else { + /* Too big chunk to cache. Call DRM directly */ + return mDrmManagerClient->pread(mDecryptHandle, data, size, offset + mOffset); + } +} } // namespace android -- cgit v1.1