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
This commit is contained in:
@@ -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<size_t> 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 {
|
||||
|
||||
@@ -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<ClientContext> mClientContext;
|
||||
|
||||
Vector<size_t> mEncryptedSizes;
|
||||
Vector<size_t> mClearSizes;
|
||||
char mCryptoPluginKey[kCryptoBlockSize];
|
||||
|
||||
void allocBufferGroup();
|
||||
|
||||
Reference in New Issue
Block a user