diff options
author | Lajos Molnar <lajos@google.com> | 2014-09-25 18:42:34 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-09-25 18:42:34 +0000 |
commit | 8761bbc7269947e9628519c8848dffd3181f0140 (patch) | |
tree | 63a316ae2e10a6f505d57aa0c7b8040cbc04d08a /media/libmediaplayerservice | |
parent | 9025e58140d00056016d8624d669b944ccf4f1b4 (diff) | |
parent | 6210ce1c6c753d9c232d18a886b2b89ab138f3bc (diff) | |
download | frameworks_av-8761bbc7269947e9628519c8848dffd3181f0140.zip frameworks_av-8761bbc7269947e9628519c8848dffd3181f0140.tar.gz frameworks_av-8761bbc7269947e9628519c8848dffd3181f0140.tar.bz2 |
am 6210ce1c: am 207fc297: Merge "mediaplayer: handle bad input in VideoFrameScheduler" into lmp-dev
* commit '6210ce1c6c753d9c232d18a886b2b89ab138f3bc':
mediaplayer: handle bad input in VideoFrameScheduler
Diffstat (limited to 'media/libmediaplayerservice')
-rw-r--r-- | media/libmediaplayerservice/VideoFrameScheduler.cpp | 18 | ||||
-rw-r--r-- | media/libmediaplayerservice/VideoFrameScheduler.h | 3 |
2 files changed, 17 insertions, 4 deletions
diff --git a/media/libmediaplayerservice/VideoFrameScheduler.cpp b/media/libmediaplayerservice/VideoFrameScheduler.cpp index 4251c4e..1a5f3e0 100644 --- a/media/libmediaplayerservice/VideoFrameScheduler.cpp +++ b/media/libmediaplayerservice/VideoFrameScheduler.cpp @@ -152,7 +152,7 @@ void VideoFrameScheduler::PLL::test() { #endif -void VideoFrameScheduler::PLL::fit( +bool VideoFrameScheduler::PLL::fit( nsecs_t phase, nsecs_t period, size_t numSamplesToUse, int64_t *a, int64_t *b, int64_t *err) { if (numSamplesToUse > mNumSamples) { @@ -187,6 +187,10 @@ void VideoFrameScheduler::PLL::fit( } int64_t div = numSamplesToUse * sumXX - sumX * sumX; + if (div == 0) { + return false; + } + int64_t a_nom = numSamplesToUse * sumXY - sumX * sumY; int64_t b_nom = sumXX * sumY - sumX * sumXY; *a = divRound(a_nom, div); @@ -198,6 +202,7 @@ void VideoFrameScheduler::PLL::fit( (long long)*a, (*a / (float)(1 << kPrecision)), (long long)*b, (*b / (float)(1 << kPrecision)), (long long)*err, (*err / (float)(1 << (kPrecision * 2)))); + return true; } void VideoFrameScheduler::PLL::prime(size_t numSamplesToUse) { @@ -226,7 +231,7 @@ void VideoFrameScheduler::PLL::prime(size_t numSamplesToUse) { deltas.sort(compare<nsecs_t>); size_t numDeltas = deltas.size(); if (numDeltas > 1) { - nsecs_t deltaMinLimit = min(deltas[0] / kMultiplesThresholdDiv, kMinPeriod); + nsecs_t deltaMinLimit = max(deltas[0] / kMultiplesThresholdDiv, kMinPeriod); nsecs_t deltaMaxLimit = deltas[numDeltas / 2] * kMultiplesThresholdDiv; for (size_t i = numDeltas / 2 + 1; i < numDeltas; ++i) { if (deltas[i] > deltaMaxLimit) { @@ -314,8 +319,15 @@ nsecs_t VideoFrameScheduler::PLL::addSample(nsecs_t time) { if (doFit) { int64_t a, b, err; + if (!fit(mPhase, mPeriod, kMaxSamplesToEstimatePeriod, &a, &b, &err)) { + // samples are not suitable for fitting. this means they are + // also not suitable for priming. + ALOGV("could not fit - keeping old period:%lld", (long long)mPeriod); + return mPeriod; + } + mRefitAt = time + kRefitRefreshPeriod; - fit(mPhase, mPeriod, kMaxSamplesToEstimatePeriod, &a, &b, &err); + mPhase += (mPeriod * b) >> kPrecision; mPeriod = (mPeriod * a) >> kPrecision; ALOGV("new phase:%lld period:%lld", (long long)mPhase, (long long)mPeriod); diff --git a/media/libmediaplayerservice/VideoFrameScheduler.h b/media/libmediaplayerservice/VideoFrameScheduler.h index 19f0787..84b27b4 100644 --- a/media/libmediaplayerservice/VideoFrameScheduler.h +++ b/media/libmediaplayerservice/VideoFrameScheduler.h @@ -71,7 +71,8 @@ private: nsecs_t mTimes[kHistorySize]; void test(); - void fit(nsecs_t phase, nsecs_t period, size_t numSamples, + // returns whether fit was successful + bool fit(nsecs_t phase, nsecs_t period, size_t numSamples, int64_t *a, int64_t *b, int64_t *err); void prime(size_t numSamples); }; |