From c49fe085767dee3ed50c11e1dcb36926724d8bd1 Mon Sep 17 00:00:00 2001 From: Edwin Wong Date: Tue, 18 Jun 2013 16:12:51 -0700 Subject: [PATCH] Fixes GTS crash on Nexus 10. When the video packets are clear, they are being combined into a full frame between MediaExtractor or DecryptCallback (where packets are never > 64k) and MediaCrypto/DecryptVideo (where we are seeing clear packets > 64k). The max block size to be passed to DecryptVideo is specified as 64K, handling of packets larger than 64K is undefined and OEM implementation-dependent. In the Nexus 10 case, it generates a SEG. fault. Solution: Add mClearSizes vector to keep track of each clear packet size for android_media_MediaExtractor_getSampleCryptoInfo() to process. In android_media_MediaExtractor_getSampleCryptoInfo(), if it does not see kKeyEncryptedSizes meta data, it will not process the clear vector that contains the actual packet sizes. Add a kKeyEncryptedSizes meta data that contains a zero length size packet to trick the JNI code to process the clear packets. related-to-bug: 9261447 Change-Id: Ib0b655a95e099856babaf649f4a95fc7f9c17d41 --- proprietary/wvm/WVMMediaSource.cpp | 35 ++++++++++++++++++++---- proprietary/wvm/include/WVMMediaSource.h | 2 ++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/proprietary/wvm/WVMMediaSource.cpp b/proprietary/wvm/WVMMediaSource.cpp index 3c454ed1..f440dece 100644 --- a/proprietary/wvm/WVMMediaSource.cpp +++ b/proprietary/wvm/WVMMediaSource.cpp @@ -279,6 +279,7 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options) mDecryptContext.Initialize(mediaBuf); mEncryptedSizes.clear(); + mClearSizes.clear(); size_t bytesRead; bool auStart; @@ -365,6 +366,7 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options) usleep(10000); mDecryptContext.Initialize(mediaBuf); mEncryptedSizes.clear(); + mClearSizes.clear(); continue; } @@ -402,14 +404,35 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options) mediaBuf->set_range(0, bytesRead + offset); - 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); + if (!mIsLiveStream) { + if (mEncryptedSizes.size()) { + mediaBuf->meta_data()->setData(kKeyEncryptedSizes, 0, + &mEncryptedSizes[0], + mEncryptedSizes.size() * sizeof(size_t)); + mediaBuf->meta_data()->setInt32(kKeyCryptoMode, + CryptoPlugin::kMode_AES_WV); #ifndef REQUIRE_SECURE_BUFFERS - mediaBuf->meta_data()->setData(kKeyCryptoKey, 0, mCryptoPluginKey, sizeof(mCryptoPluginKey)); + mediaBuf->meta_data()->setData(kKeyCryptoKey, 0, + mCryptoPluginKey, + sizeof(mCryptoPluginKey)); #endif + } else { + // Fixes b/9261447: GTS crashed on Nexus 10 + Vector zeroEncryptedSizes; + size_t zeroValue = 0; + zeroEncryptedSizes.insertAt(zeroValue, 0, + mClearSizes.size()); + mediaBuf->meta_data()->setData(kKeyEncryptedSizes, 0, + &zeroEncryptedSizes[0], + zeroEncryptedSizes.size() * sizeof(size_t)); + + mediaBuf->meta_data()->setData(kKeyPlainSizes, 0, + &mClearSizes[0], + mClearSizes.size() * sizeof(size_t)); + mediaBuf->meta_data()->setInt32(kKeyCryptoMode, + CryptoPlugin::kMode_Unencrypted); + } } #if 0 @@ -468,6 +491,8 @@ void WVMMediaSource::DecryptCallback(WVEsSelector esType, void* input, void* out // just determine crypto unit boundaries if (key) { source->addEncryptedSize(length); + } else { + source->addClearSize(length); } memcpy((uint8_t *)context.mMediaBuf->data() + context.mOffset, input, length); } else { diff --git a/proprietary/wvm/include/WVMMediaSource.h b/proprietary/wvm/include/WVMMediaSource.h index 66e57ad8..5f0e8a81 100644 --- a/proprietary/wvm/include/WVMMediaSource.h +++ b/proprietary/wvm/include/WVMMediaSource.h @@ -42,6 +42,7 @@ public: virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL); void addEncryptedSize(size_t size) { mEncryptedSizes.push_back(size); } + void addClearSize(size_t size) { mClearSizes.push_back(size); } static int sLastError; @@ -103,6 +104,7 @@ private: sp mClientContext; Vector mEncryptedSizes; + Vector mClearSizes; char mCryptoPluginKey[kCryptoBlockSize]; void allocBufferGroup();