summaryrefslogtreecommitdiffstats
path: root/media/libmediaplayerservice
diff options
context:
space:
mode:
authorLajos Molnar <lajos@google.com>2014-09-25 18:42:34 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2014-09-25 18:42:34 +0000
commit8761bbc7269947e9628519c8848dffd3181f0140 (patch)
tree63a316ae2e10a6f505d57aa0c7b8040cbc04d08a /media/libmediaplayerservice
parent9025e58140d00056016d8624d669b944ccf4f1b4 (diff)
parent6210ce1c6c753d9c232d18a886b2b89ab138f3bc (diff)
downloadframeworks_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.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);
};