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:
Edwin Wong
2013-06-18 16:12:51 -07:00
parent aae152cf78
commit c49fe08576
2 changed files with 32 additions and 5 deletions

View File

@@ -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 {

View File

@@ -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();