Loading media/libstagefright/MediaCodec.cpp +51 −18 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ #include <media/stagefright/foundation/avc_utils.h> #include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/ACodec.h> #include <media/stagefright/BatteryChecker.h> #include <media/stagefright/BufferProducerWrapper.h> #include <media/stagefright/MediaCodec.h> #include <media/stagefright/MediaCodecList.h> Loading Loading @@ -116,7 +117,6 @@ static bool isResourceError(status_t err) { static const int kMaxRetry = 2; static const int kMaxReclaimWaitTimeInUs = 500000; // 0.5s static const int kNumBuffersAlign = 16; static const int kBatteryStatsTimeoutUs = 3000000ll; // 3 seconds //////////////////////////////////////////////////////////////////////////////// Loading Loading @@ -539,10 +539,7 @@ MediaCodec::MediaCodec(const sp<ALooper> &looper, pid_t pid, uid_t uid) mHaveInputSurface(false), mHavePendingInputBuffers(false), mCpuBoostRequested(false), mLatencyUnknown(0), mLastActivityTimeUs(-1ll), mBatteryStatNotified(false), mBatteryCheckerGeneration(0) { mLatencyUnknown(0) { if (uid == kNoUid) { mUid = IPCThreadState::self()->getCallingUid(); } else { Loading Loading @@ -755,7 +752,11 @@ void MediaCodec::statsBufferSent(int64_t presentationUs) { return; } scheduleBatteryCheckerIfNeeded(); if (mBatteryChecker != nullptr) { mBatteryChecker->onCodecActivity([this] () { addResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1); }); } const int64_t nowNs = systemTime(SYSTEM_TIME_MONOTONIC); BufferFlightTiming_t startdata = { presentationUs, nowNs }; Loading Loading @@ -791,7 +792,11 @@ void MediaCodec::statsBufferReceived(int64_t presentationUs) { return; } scheduleBatteryCheckerIfNeeded(); if (mBatteryChecker != nullptr) { mBatteryChecker->onCodecActivity([this] () { addResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1); }); } BufferFlightTiming_t startdata; bool valid = false; Loading Loading @@ -981,6 +986,10 @@ status_t MediaCodec::init(const AString &name) { mAnalyticsItem->setCString(kCodecMode, mIsVideo ? kCodecModeVideo : kCodecModeAudio); } if (mIsVideo) { mBatteryChecker = new BatteryChecker(new AMessage(kWhatCheckBatteryStats, this)); } status_t err; Vector<MediaResource> resources; MediaResource::Type type = Loading Loading @@ -1706,19 +1715,27 @@ void MediaCodec::requestCpuBoostIfNeeded() { } } void MediaCodec::scheduleBatteryCheckerIfNeeded() { if (!mIsVideo || !isExecuting()) { BatteryChecker::BatteryChecker(const sp<AMessage> &msg, int64_t timeoutUs) : mTimeoutUs(timeoutUs) , mLastActivityTimeUs(-1ll) , mBatteryStatNotified(false) , mBatteryCheckerGeneration(0) , mIsExecuting(false) , mBatteryCheckerMsg(msg) {} void BatteryChecker::onCodecActivity(std::function<void()> batteryOnCb) { if (!isExecuting()) { // ignore if not executing return; } if (!mBatteryStatNotified) { addResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1); batteryOnCb(); mBatteryStatNotified = true; sp<AMessage> msg = new AMessage(kWhatCheckBatteryStats, this); sp<AMessage> msg = mBatteryCheckerMsg->dup(); msg->setInt32("generation", mBatteryCheckerGeneration); // post checker and clear last activity time msg->post(kBatteryStatsTimeoutUs); msg->post(mTimeoutUs); mLastActivityTimeUs = -1ll; } else { // update last activity time Loading @@ -1726,7 +1743,8 @@ void MediaCodec::scheduleBatteryCheckerIfNeeded() { } } void MediaCodec::onBatteryChecker(const sp<AMessage> &msg) { void BatteryChecker::onCheckBatteryTimer( const sp<AMessage> &msg, std::function<void()> batteryOffCb) { // ignore if this checker already expired because the client resource was removed int32_t generation; if (!msg->findInt32("generation", &generation) Loading @@ -1736,15 +1754,20 @@ void MediaCodec::onBatteryChecker(const sp<AMessage> &msg) { if (mLastActivityTimeUs < 0ll) { // timed out inactive, do not repost checker removeResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1); batteryOffCb(); mBatteryStatNotified = false; } else { // repost checker and clear last activity time msg->post(kBatteryStatsTimeoutUs + mLastActivityTimeUs - ALooper::GetNowUs()); msg->post(mTimeoutUs + mLastActivityTimeUs - ALooper::GetNowUs()); mLastActivityTimeUs = -1ll; } } void BatteryChecker::onClientRemoved() { mBatteryStatNotified = false; mBatteryCheckerGeneration++; } //////////////////////////////////////////////////////////////////////////////// void MediaCodec::cancelPendingDequeueOperations() { Loading Loading @@ -2382,8 +2405,10 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { mFlags &= ~kFlagIsComponentAllocated; // off since we're removing all resources including the battery on mBatteryStatNotified = false; mBatteryCheckerGeneration++; if (mBatteryChecker != nullptr) { mBatteryChecker->onClientRemoved(); } mResourceManagerService->removeClient(getId(mResourceManagerClient)); (new AMessage)->postReply(mReplyID); Loading Loading @@ -3097,7 +3122,11 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { case kWhatCheckBatteryStats: { onBatteryChecker(msg); if (mBatteryChecker != nullptr) { mBatteryChecker->onCheckBatteryTimer(msg, [this] () { removeResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1); }); } break; } Loading Loading @@ -3197,6 +3226,10 @@ void MediaCodec::setState(State newState) { mState = newState; if (mBatteryChecker != nullptr) { mBatteryChecker->setExecuting(isExecuting()); } cancelPendingDequeueOperations(); } Loading media/libstagefright/TEST_MAPPING +3 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,9 @@ "include-annotation": "android.platform.test.annotations.RequiresDevice" } ] }, { "name": "BatteryChecker_test" } ] } media/libstagefright/include/media/stagefright/BatteryChecker.h 0 → 100644 +47 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BATTERY_CHECKER_H_ #define BATTERY_CHECKER_H_ #include <media/stagefright/foundation/AMessage.h> namespace android { struct BatteryChecker : public RefBase { BatteryChecker(const sp<AMessage> &msg, int64_t timeout = 3000000ll); void setExecuting(bool executing) { mIsExecuting = executing; } void onCodecActivity(std::function<void()> batteryOnCb); void onCheckBatteryTimer(const sp<AMessage>& msg, std::function<void()> batteryOffCb); void onClientRemoved(); private: const int64_t mTimeoutUs; int64_t mLastActivityTimeUs; bool mBatteryStatNotified; int32_t mBatteryCheckerGeneration; bool mIsExecuting; sp<AMessage> mBatteryCheckerMsg; bool isExecuting() { return mIsExecuting; } DISALLOW_EVIL_CONSTRUCTORS(BatteryChecker); }; } // namespace android #endif // BATTERY_CHECKER_H_ media/libstagefright/include/media/stagefright/MediaCodec.h +2 −5 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ struct ABuffer; struct AMessage; struct AReplyToken; struct AString; struct BatteryChecker; class BufferChannelBase; struct CodecBase; class IBatteryStats; Loading Loading @@ -463,11 +464,7 @@ private: Mutex mLatencyLock; int64_t mLatencyUnknown; // buffers for which we couldn't calculate latency int64_t mLastActivityTimeUs; bool mBatteryStatNotified; int32_t mBatteryCheckerGeneration; void onBatteryChecker(const sp<AMessage>& msg); void scheduleBatteryCheckerIfNeeded(); sp<BatteryChecker> mBatteryChecker; void statsBufferSent(int64_t presentationUs); void statsBufferReceived(int64_t presentationUs); Loading media/libstagefright/tests/Android.bp +18 −0 Original line number Diff line number Diff line Loading @@ -27,3 +27,21 @@ cc_test { "-Wall", ], } cc_test { name: "BatteryChecker_test", srcs: ["BatteryChecker_test.cpp"], test_suites: ["device-tests"], shared_libs: [ "libstagefright", "libstagefright_foundation", "libutils", "liblog", ], cflags: [ "-Werror", "-Wall", ], } No newline at end of file Loading
media/libstagefright/MediaCodec.cpp +51 −18 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ #include <media/stagefright/foundation/avc_utils.h> #include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/ACodec.h> #include <media/stagefright/BatteryChecker.h> #include <media/stagefright/BufferProducerWrapper.h> #include <media/stagefright/MediaCodec.h> #include <media/stagefright/MediaCodecList.h> Loading Loading @@ -116,7 +117,6 @@ static bool isResourceError(status_t err) { static const int kMaxRetry = 2; static const int kMaxReclaimWaitTimeInUs = 500000; // 0.5s static const int kNumBuffersAlign = 16; static const int kBatteryStatsTimeoutUs = 3000000ll; // 3 seconds //////////////////////////////////////////////////////////////////////////////// Loading Loading @@ -539,10 +539,7 @@ MediaCodec::MediaCodec(const sp<ALooper> &looper, pid_t pid, uid_t uid) mHaveInputSurface(false), mHavePendingInputBuffers(false), mCpuBoostRequested(false), mLatencyUnknown(0), mLastActivityTimeUs(-1ll), mBatteryStatNotified(false), mBatteryCheckerGeneration(0) { mLatencyUnknown(0) { if (uid == kNoUid) { mUid = IPCThreadState::self()->getCallingUid(); } else { Loading Loading @@ -755,7 +752,11 @@ void MediaCodec::statsBufferSent(int64_t presentationUs) { return; } scheduleBatteryCheckerIfNeeded(); if (mBatteryChecker != nullptr) { mBatteryChecker->onCodecActivity([this] () { addResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1); }); } const int64_t nowNs = systemTime(SYSTEM_TIME_MONOTONIC); BufferFlightTiming_t startdata = { presentationUs, nowNs }; Loading Loading @@ -791,7 +792,11 @@ void MediaCodec::statsBufferReceived(int64_t presentationUs) { return; } scheduleBatteryCheckerIfNeeded(); if (mBatteryChecker != nullptr) { mBatteryChecker->onCodecActivity([this] () { addResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1); }); } BufferFlightTiming_t startdata; bool valid = false; Loading Loading @@ -981,6 +986,10 @@ status_t MediaCodec::init(const AString &name) { mAnalyticsItem->setCString(kCodecMode, mIsVideo ? kCodecModeVideo : kCodecModeAudio); } if (mIsVideo) { mBatteryChecker = new BatteryChecker(new AMessage(kWhatCheckBatteryStats, this)); } status_t err; Vector<MediaResource> resources; MediaResource::Type type = Loading Loading @@ -1706,19 +1715,27 @@ void MediaCodec::requestCpuBoostIfNeeded() { } } void MediaCodec::scheduleBatteryCheckerIfNeeded() { if (!mIsVideo || !isExecuting()) { BatteryChecker::BatteryChecker(const sp<AMessage> &msg, int64_t timeoutUs) : mTimeoutUs(timeoutUs) , mLastActivityTimeUs(-1ll) , mBatteryStatNotified(false) , mBatteryCheckerGeneration(0) , mIsExecuting(false) , mBatteryCheckerMsg(msg) {} void BatteryChecker::onCodecActivity(std::function<void()> batteryOnCb) { if (!isExecuting()) { // ignore if not executing return; } if (!mBatteryStatNotified) { addResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1); batteryOnCb(); mBatteryStatNotified = true; sp<AMessage> msg = new AMessage(kWhatCheckBatteryStats, this); sp<AMessage> msg = mBatteryCheckerMsg->dup(); msg->setInt32("generation", mBatteryCheckerGeneration); // post checker and clear last activity time msg->post(kBatteryStatsTimeoutUs); msg->post(mTimeoutUs); mLastActivityTimeUs = -1ll; } else { // update last activity time Loading @@ -1726,7 +1743,8 @@ void MediaCodec::scheduleBatteryCheckerIfNeeded() { } } void MediaCodec::onBatteryChecker(const sp<AMessage> &msg) { void BatteryChecker::onCheckBatteryTimer( const sp<AMessage> &msg, std::function<void()> batteryOffCb) { // ignore if this checker already expired because the client resource was removed int32_t generation; if (!msg->findInt32("generation", &generation) Loading @@ -1736,15 +1754,20 @@ void MediaCodec::onBatteryChecker(const sp<AMessage> &msg) { if (mLastActivityTimeUs < 0ll) { // timed out inactive, do not repost checker removeResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1); batteryOffCb(); mBatteryStatNotified = false; } else { // repost checker and clear last activity time msg->post(kBatteryStatsTimeoutUs + mLastActivityTimeUs - ALooper::GetNowUs()); msg->post(mTimeoutUs + mLastActivityTimeUs - ALooper::GetNowUs()); mLastActivityTimeUs = -1ll; } } void BatteryChecker::onClientRemoved() { mBatteryStatNotified = false; mBatteryCheckerGeneration++; } //////////////////////////////////////////////////////////////////////////////// void MediaCodec::cancelPendingDequeueOperations() { Loading Loading @@ -2382,8 +2405,10 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { mFlags &= ~kFlagIsComponentAllocated; // off since we're removing all resources including the battery on mBatteryStatNotified = false; mBatteryCheckerGeneration++; if (mBatteryChecker != nullptr) { mBatteryChecker->onClientRemoved(); } mResourceManagerService->removeClient(getId(mResourceManagerClient)); (new AMessage)->postReply(mReplyID); Loading Loading @@ -3097,7 +3122,11 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { case kWhatCheckBatteryStats: { onBatteryChecker(msg); if (mBatteryChecker != nullptr) { mBatteryChecker->onCheckBatteryTimer(msg, [this] () { removeResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1); }); } break; } Loading Loading @@ -3197,6 +3226,10 @@ void MediaCodec::setState(State newState) { mState = newState; if (mBatteryChecker != nullptr) { mBatteryChecker->setExecuting(isExecuting()); } cancelPendingDequeueOperations(); } Loading
media/libstagefright/TEST_MAPPING +3 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,9 @@ "include-annotation": "android.platform.test.annotations.RequiresDevice" } ] }, { "name": "BatteryChecker_test" } ] }
media/libstagefright/include/media/stagefright/BatteryChecker.h 0 → 100644 +47 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BATTERY_CHECKER_H_ #define BATTERY_CHECKER_H_ #include <media/stagefright/foundation/AMessage.h> namespace android { struct BatteryChecker : public RefBase { BatteryChecker(const sp<AMessage> &msg, int64_t timeout = 3000000ll); void setExecuting(bool executing) { mIsExecuting = executing; } void onCodecActivity(std::function<void()> batteryOnCb); void onCheckBatteryTimer(const sp<AMessage>& msg, std::function<void()> batteryOffCb); void onClientRemoved(); private: const int64_t mTimeoutUs; int64_t mLastActivityTimeUs; bool mBatteryStatNotified; int32_t mBatteryCheckerGeneration; bool mIsExecuting; sp<AMessage> mBatteryCheckerMsg; bool isExecuting() { return mIsExecuting; } DISALLOW_EVIL_CONSTRUCTORS(BatteryChecker); }; } // namespace android #endif // BATTERY_CHECKER_H_
media/libstagefright/include/media/stagefright/MediaCodec.h +2 −5 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ struct ABuffer; struct AMessage; struct AReplyToken; struct AString; struct BatteryChecker; class BufferChannelBase; struct CodecBase; class IBatteryStats; Loading Loading @@ -463,11 +464,7 @@ private: Mutex mLatencyLock; int64_t mLatencyUnknown; // buffers for which we couldn't calculate latency int64_t mLastActivityTimeUs; bool mBatteryStatNotified; int32_t mBatteryCheckerGeneration; void onBatteryChecker(const sp<AMessage>& msg); void scheduleBatteryCheckerIfNeeded(); sp<BatteryChecker> mBatteryChecker; void statsBufferSent(int64_t presentationUs); void statsBufferReceived(int64_t presentationUs); Loading
media/libstagefright/tests/Android.bp +18 −0 Original line number Diff line number Diff line Loading @@ -27,3 +27,21 @@ cc_test { "-Wall", ], } cc_test { name: "BatteryChecker_test", srcs: ["BatteryChecker_test.cpp"], test_suites: ["device-tests"], shared_libs: [ "libstagefright", "libstagefright_foundation", "libutils", "liblog", ], cflags: [ "-Werror", "-Wall", ], } No newline at end of file