From 2e0e32f9f7ba1973beb377878651db06f526d7c3 Mon Sep 17 00:00:00 2001 From: "John \"Juce\" Bruce" Date: Mon, 10 Sep 2012 18:42:48 -0700 Subject: [PATCH] When Running in MediaCodec Mode, Widevine Freezes If You Rewind There was a subtle interaction between Widevine's libraries and MediaCodec mode. Widevine's code assumed (erroneously) that video seeks would always happen before audio seeks, and because we can't seek audio and video independently from each other, we would ignore audio seeks but respect video seeks. This led to a problem since MediaCodec mode calls seeks in arbitrary order. Fix is to always respect the first request we get to seek and ignore the second. Bug: 6793514 Change-Id: Ic9ec60e0e0f606c7a0de6283dd4c30318eebdbad --- proprietary/wvm/WVMMediaSource.cpp | 13 +++++++++++-- proprietary/wvm/include/WVMMediaSource.h | 6 +++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/proprietary/wvm/WVMMediaSource.cpp b/proprietary/wvm/WVMMediaSource.cpp index e42e63c7..434de1f6 100644 --- a/proprietary/wvm/WVMMediaSource.cpp +++ b/proprietary/wvm/WVMMediaSource.cpp @@ -2,6 +2,7 @@ * Copyright (C) 2011 Google, Inc. All Rights Reserved */ +//#define LOG_NDEBUG 0 #define LOG_TAG "WVMMediaSource" #include @@ -24,6 +25,7 @@ static void _cb(int code) } status_t WVMMediaSource::sLastError = NO_ERROR; +int64_t WVMMediaSource::mLastSeekTimeUs = -1; WVMMediaSource::WVMMediaSource(WVSession *session, WVEsSelector esSelector, const sp &metaData, bool isLive, @@ -246,8 +248,10 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options) // prior to the specified time. seekNextSync = true; } else { - // Let video stream control seek - if (mESSelector == WV_EsSelector_Video) { + // Whichever stream gets the seek first should do the actual seeking. + // To keep from double-seeking, we share the information about who + // has seeked most recently. + if (mLastSeekTimeUs != seekTimeUs) { float scaleUsed; std::string when = usecToNPT(seekTimeUs) + std::string("-"); WVStatus result = WV_Play(mSession, 1.0, &scaleUsed, when ); @@ -255,6 +259,11 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options) ALOGE("WV_Play returned status %d in WVMMediaSource::read\n", result); return ERROR_IO; } + mLastSeekTimeUs = seekTimeUs; + } else { + // Now that both video and audio were seeked, clear the shared + // data. + mLastSeekTimeUs = -1; } } } diff --git a/proprietary/wvm/include/WVMMediaSource.h b/proprietary/wvm/include/WVMMediaSource.h index 78c13009..44305b36 100644 --- a/proprietary/wvm/include/WVMMediaSource.h +++ b/proprietary/wvm/include/WVMMediaSource.h @@ -69,17 +69,16 @@ public: memcpy(mCryptoPluginKey, key, sizeof(mCryptoPluginKey)); } -private: - DecryptContext mDecryptContext; - protected: virtual ~WVMMediaSource(); private: + static int64_t mLastSeekTimeUs; Mutex mLock; WVSession *mSession; WVEsSelector mESSelector; // indicates audio vs. video + DecryptContext mDecryptContext; sp mTrackMetaData; @@ -94,6 +93,7 @@ private: MediaBufferGroup *mGroup; int64_t mKeyTime; + unsigned long long mDts; unsigned long long mPts;