diff --git a/proprietary/drmwvmplugin/lib/arm/libwvdrm_L1.so b/proprietary/drmwvmplugin/lib/arm/libwvdrm_L1.so index 86f6321c..9df369a6 100644 Binary files a/proprietary/drmwvmplugin/lib/arm/libwvdrm_L1.so and b/proprietary/drmwvmplugin/lib/arm/libwvdrm_L1.so differ diff --git a/proprietary/drmwvmplugin/lib/arm/libwvocs_L1.a b/proprietary/drmwvmplugin/lib/arm/libwvocs_L1.a index 61255efd..7e427d99 100644 Binary files a/proprietary/drmwvmplugin/lib/arm/libwvocs_L1.a and b/proprietary/drmwvmplugin/lib/arm/libwvocs_L1.a differ diff --git a/proprietary/streamcontrol/include/WVStreamControlAPI.h b/proprietary/streamcontrol/include/WVStreamControlAPI.h index 1459475e..fb7f8153 100644 --- a/proprietary/streamcontrol/include/WVStreamControlAPI.h +++ b/proprietary/streamcontrol/include/WVStreamControlAPI.h @@ -70,6 +70,7 @@ typedef void (*WVSocketInfoCallback)(int fd, int status, void * context); // [in] dts - Decode timestamp, 90 KHz clock // [in] pts - Presentation timestamp, 90 KHz clock // [in] au_end - Indicates end of Access Unit (last CU in frame) +// [in] context - Client context established from WV_Setup // // Returns: // - WV_Status_OK: Decryption succeeded @@ -78,7 +79,8 @@ typedef void (*WVSocketInfoCallback)(int fd, int status, void * context); // - Error code indicating problem. Causes playback to halt. // typedef WVStatus (*WVDecryptCallback)(WVEsSelector es_type, void* input, void* output, size_t length, - int key, unsigned long long dts, unsigned long long pts, bool au_end); + int key, unsigned long long dts, unsigned long long pts, + bool au_end, void *context); enum WVDecryptCallbackMode { WVDecryptCallbackMode_MultiCU = 0, // WVDecryptCallback called repeatedly until buffer exhausted diff --git a/proprietary/streamcontrol/lib/arm/libWVStreamControlAPI_L1.so b/proprietary/streamcontrol/lib/arm/libWVStreamControlAPI_L1.so index bb513ba9..801606f6 100644 Binary files a/proprietary/streamcontrol/lib/arm/libWVStreamControlAPI_L1.so and b/proprietary/streamcontrol/lib/arm/libWVStreamControlAPI_L1.so differ diff --git a/proprietary/wvm/WVMExtractorImpl.cpp b/proprietary/wvm/WVMExtractorImpl.cpp index ddd202dc..4c387773 100644 --- a/proprietary/wvm/WVMExtractorImpl.cpp +++ b/proprietary/wvm/WVMExtractorImpl.cpp @@ -98,7 +98,8 @@ WVMExtractorImpl::WVMExtractorImpl(sp dataSource) mIsLiveStream(false), mSession(NULL), mSetupStatus(OK), - mUIDIsSet(false) + mUIDIsSet(false), + mCryptoPluginMode(false) { dataSource->getDrmInfo(sDecryptHandle, &sDrmManagerClient); @@ -340,12 +341,18 @@ status_t WVMExtractorImpl::readMetaData() mVideoSource->delegateDataSource(mDataSource); - mFileMetaData->setCString(kKeyMIMEType, "video/mp4"); + mFileMetaData->setCString(kKeyMIMEType, "video/wvm"); mHaveMetaData = true; mInfoListener->configureHeartbeat(); + if (mCryptoPluginMode) { + // In crypto plugin mode, need to trigger the drm plugin to begin + // license use on playback since the media player isn't involved. + sDrmManagerClient->setPlaybackStatus(sDecryptHandle, Playback::START, 0); + } + return OK; } @@ -514,6 +521,18 @@ bool WVMExtractorImpl::getAdaptiveStreamingMode() const return mUseAdaptiveStreaming; } +void WVMExtractorImpl::setCryptoPluginMode(bool cryptoPluginMode) +{ + //ALOGD("WVMExtractorImpl::setCryptoPluginMode(%d)", cryptoPluginMode); + mCryptoPluginMode = cryptoPluginMode; +} + +bool WVMExtractorImpl::getCryptoPluginMode() const +{ + //ALOGD("WVMExtractorImpl::getCryptoPluginMode - %d", mCryptoPluginMode); + return mCryptoPluginMode; +} + void WVMExtractorImpl::setUID(uid_t uid) { //ALOGD("WVMExtractorImpl::setUID(%d)", (uint32_t)uid); diff --git a/proprietary/wvm/WVMMediaSource.cpp b/proprietary/wvm/WVMMediaSource.cpp index c5858709..0532a90d 100644 --- a/proprietary/wvm/WVMMediaSource.cpp +++ b/proprietary/wvm/WVMMediaSource.cpp @@ -11,6 +11,8 @@ #include "media/stagefright/foundation/ADebug.h" #include "media/stagefright/MediaErrors.h" #include "media/stagefright/MediaDefs.h" +#include "media/stagefright/MetaData.h" +#include "media/hardware/CryptoAPI.h" #include "AndroidHooks.h" namespace android { @@ -112,19 +114,11 @@ status_t WVMMediaSource::start(MetaData *) ALOGE("WV_Play returned status %d in WVMMediaSource::start\n", result); return ERROR_IO; } - -#ifndef REQUIRE_SECURE_BUFFERS - allocBufferGroup(); -#else - if (mIsLiveStream) { - allocBufferGroup(); - } -#endif - } else { - // audio - allocBufferGroup(); } + if (!mGroup) + allocBufferGroup(); + return OK; } @@ -239,7 +233,8 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options) } #ifdef REQUIRE_SECURE_BUFFERS - sDecryptContext[mESSelector].Initialize(mediaBuf); + mDecryptContext.Initialize(mediaBuf); + mEncryptedSizes.clear(); #endif size_t bytesRead; @@ -302,7 +297,7 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options) #ifdef REQUIRE_SECURE_BUFFERS if (mESSelector == WV_EsSelector_Video && !mIsLiveStream) { - bytesRead = sDecryptContext[mESSelector].mOffset; + bytesRead = mDecryptContext.mOffset; } #endif @@ -326,7 +321,8 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options) // drop frames up to next sync if requested usleep(10000); #ifdef REQUIRE_SECURE_BUFFERS - sDecryptContext[mESSelector].Initialize(mediaBuf); + mDecryptContext.Initialize(mediaBuf); + mEncryptedSizes.clear(); #endif continue; } @@ -365,6 +361,14 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options) mediaBuf->set_range(0, bytesRead + offset); +#ifdef REQUIRE_SECURE_BUFFERS + if (!mIsLiveStream && mEncryptedSizes.size()) { + mediaBuf->meta_data()->setData(kKeyEncryptedSizes, 0, &mEncryptedSizes[0], + mEncryptedSizes.size() * sizeof(size_t)); + mediaBuf->meta_data()->setInt32(kKeyCryptoMode, CryptoPlugin::kMode_AES_WV); + } +#endif + #if 0 // debug code - log packets to files char filename[32]; @@ -397,41 +401,54 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options) #ifdef REQUIRE_SECURE_BUFFERS -WVMMediaSource::DecryptContext WVMMediaSource::sDecryptContext[2] = {}; - WVStatus WVMMediaSource::DecryptCallback(WVEsSelector esType, void* input, void* output, size_t length, - int key, unsigned long long dts, unsigned long long pts, bool au_end) + int key, unsigned long long dts, unsigned long long pts, bool au_end, + void *obj) { //ALOGD("DecryptCallback(type=%d, in=%p, out=%p, len=%d, key=%d\n", // (int)esType, input, output, length, key); - DecryptContext &context = sDecryptContext[esType]; + WVMExtractorImpl *extractor = (WVMExtractorImpl *)obj; + sp source; + if (esType == WV_EsSelector_Video) + source = extractor->getVideoSource(); + else + source = extractor->getAudioSource(); + DecryptContext &context = source->getDecryptContext(); + OEMCrypto_UINT32 copied = length; OEMCryptoResult result; - WVStatus status; + WVStatus status = WV_Status_OK; unsigned char *iv = NULL; - if (key) - iv = context.mIV; - - if (esType == WV_EsSelector_Video) { - result = OEMCrypto_DecryptVideo(iv, (OEMCrypto_UINT8 *)input, length, - (OEMCrypto_UINT32)(char *)context.mMediaBuf->data(), - context.mOffset, &copied); + if (extractor->getCryptoPluginMode()) { + // just determine crypto unit boundaries + if (key) { + source->addEncryptedSize(length); + } } else { - result = OEMCrypto_DecryptAudio(iv, (OEMCrypto_UINT8 *)input, length, - (OEMCrypto_UINT8 *)context.mMediaBuf->data() + context.mOffset, - &copied); - } + // do decrypt + if (key) + iv = context.mIV; - if (result == OEMCrypto_SUCCESS) { - status = WV_Status_OK; - } - else { - status = WV_Status_Unknown; - ALOGD("OEMCrypto decrypt failure: %d", result); - } + if (esType == WV_EsSelector_Video) { + result = OEMCrypto_DecryptVideo(iv, (OEMCrypto_UINT8 *)input, length, + (OEMCrypto_UINT32)(char *)context.mMediaBuf->data(), + context.mOffset, &copied); + } else { + result = OEMCrypto_DecryptAudio(iv, (OEMCrypto_UINT8 *)input, length, + (OEMCrypto_UINT8 *)context.mMediaBuf->data() + context.mOffset, + &copied); + } - context.mOffset += copied; + if (result == OEMCrypto_SUCCESS) { + status = WV_Status_OK; + } else { + status = WV_Status_Unknown; + ALOGD("OEMCrypto decrypt failure: %d", result); + } + + context.mOffset += copied; + } return status; } diff --git a/proprietary/wvm/include/WVMExtractorImpl.h b/proprietary/wvm/include/WVMExtractorImpl.h index 2d4ea058..d857aef0 100644 --- a/proprietary/wvm/include/WVMExtractorImpl.h +++ b/proprietary/wvm/include/WVMExtractorImpl.h @@ -34,11 +34,18 @@ public: virtual sp getMetaData(); virtual int64_t getCachedDurationUs(status_t *finalStatus); + virtual void setAdaptiveStreamingMode(bool adaptive); bool getAdaptiveStreamingMode() const; + virtual void setCryptoPluginMode(bool cryptoPluginMode); + bool getCryptoPluginMode() const; + virtual void setUID(uid_t uid); + sp getAudioSource() const { return mAudioSource; } + sp getVideoSource() const { return mVideoSource; } + static void SocketInfoCallback(int fd, int op, void *context); static void cleanup(); @@ -69,6 +76,14 @@ private: bool mUIDIsSet; uid_t mUID; + // + // if in CryptoPlugin mode, the extractor doesn't decrypt, + // it just accumulates the ranges of data requiring decryption + // into the MediaBuffer's metadata, the decryption happens + // later via the CryptoPlugin + // + bool mCryptoPluginMode; + status_t readMetaData(); const static size_t kStreamCacheSize = 10 * 1024 * 1024; diff --git a/proprietary/wvm/include/WVMMediaSource.h b/proprietary/wvm/include/WVMMediaSource.h index c9401475..9d866bcf 100644 --- a/proprietary/wvm/include/WVMMediaSource.h +++ b/proprietary/wvm/include/WVMMediaSource.h @@ -38,6 +38,8 @@ public: virtual status_t setBuffers(const Vector &buffers); virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL); + void addEncryptedSize(size_t size) { mEncryptedSizes.push_back(size); } + static int sLastError; #ifdef REQUIRE_SECURE_BUFFERS @@ -53,10 +55,13 @@ public: static const int kCryptoBlockSize = 16; unsigned char mIV[kCryptoBlockSize]; }; - static WVStatus DecryptCallback(WVEsSelector esType, void* input, void* output, size_t length, - int key, unsigned long long dts, unsigned long long pts, bool au_end); - static DecryptContext sDecryptContext[2]; // audio vs. video + static WVStatus DecryptCallback(WVEsSelector esType, void* input, void* output, size_t length, + int key, unsigned long long dts, unsigned long long pts, + bool au_end, void *context); + DecryptContext& getDecryptContext() { return mDecryptContext; } +private: + DecryptContext mDecryptContext; #endif protected: @@ -74,6 +79,7 @@ private: bool mLogOnce; bool mIsLiveStream; bool mNewSegment; + bool mCryptoPluginMode; MediaBufferGroup *mGroup; @@ -83,6 +89,8 @@ private: sp mFileSource; sp mDataSource; + Vector mEncryptedSizes; + void allocBufferGroup(); WVMMediaSource(const WVMMediaSource &);