summaryrefslogtreecommitdiffstats
path: root/media/libmediaplayerservice
diff options
context:
space:
mode:
authorLajos Molnar <lajos@google.com>2014-09-24 11:30:21 -0700
committerLajos Molnar <lajos@google.com>2014-09-24 17:21:46 -0700
commit5d6fb5e41f57a71bd5b2902dc8334825de7bdcc0 (patch)
tree78afc8a61fda371dbc9c9bbb53156283ca0143ba /media/libmediaplayerservice
parentcae1c0fa3f4d5e2387f05a6055bf356914851c4b (diff)
downloadframeworks_av-5d6fb5e41f57a71bd5b2902dc8334825de7bdcc0.zip
frameworks_av-5d6fb5e41f57a71bd5b2902dc8334825de7bdcc0.tar.gz
frameworks_av-5d6fb5e41f57a71bd5b2902dc8334825de7bdcc0.tar.bz2
mediaplayer: handle bad input in VideoFrameScheduler
Bug: 17626098 Change-Id: I2ae22ed43b35ff532a47818b118dd328ce2abf63
Diffstat (limited to 'media/libmediaplayerservice')
-rw-r--r--media/libmediaplayerservice/VideoFrameScheduler.cpp18
-rw-r--r--media/libmediaplayerservice/VideoFrameScheduler.h3
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);
};