diff options
author | Lajos Molnar <lajos@google.com> | 2014-09-25 01:14:34 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-09-25 01:14:35 +0000 |
commit | 207fc297cb388c1466b7e0ef35de9d8b13830b37 (patch) | |
tree | c2ca77a908dc83b349cf68a79a9e332df4efc2ad /media | |
parent | 4a34b9a4759d7dcc2d2ad5bd96ea8477915dd67a (diff) | |
parent | 5d6fb5e41f57a71bd5b2902dc8334825de7bdcc0 (diff) | |
download | frameworks_av-207fc297cb388c1466b7e0ef35de9d8b13830b37.zip frameworks_av-207fc297cb388c1466b7e0ef35de9d8b13830b37.tar.gz frameworks_av-207fc297cb388c1466b7e0ef35de9d8b13830b37.tar.bz2 |
Merge "mediaplayer: handle bad input in VideoFrameScheduler" into lmp-dev
Diffstat (limited to 'media')
-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); }; |