Loading media/libstagefright/MediaCodec.cpp +51 −18 Original line number Original line Diff line number Diff line Loading @@ -48,6 +48,7 @@ #include <media/stagefright/foundation/avc_utils.h> #include <media/stagefright/foundation/avc_utils.h> #include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/ACodec.h> #include <media/stagefright/ACodec.h> #include <media/stagefright/BatteryChecker.h> #include <media/stagefright/BufferProducerWrapper.h> #include <media/stagefright/BufferProducerWrapper.h> #include <media/stagefright/MediaCodec.h> #include <media/stagefright/MediaCodec.h> #include <media/stagefright/MediaCodecList.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 kMaxRetry = 2; static const int kMaxReclaimWaitTimeInUs = 500000; // 0.5s static const int kMaxReclaimWaitTimeInUs = 500000; // 0.5s static const int kNumBuffersAlign = 16; 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), mHaveInputSurface(false), mHavePendingInputBuffers(false), mHavePendingInputBuffers(false), mCpuBoostRequested(false), mCpuBoostRequested(false), mLatencyUnknown(0), mLatencyUnknown(0) { mLastActivityTimeUs(-1ll), mBatteryStatNotified(false), mBatteryCheckerGeneration(0) { if (uid == kNoUid) { if (uid == kNoUid) { mUid = IPCThreadState::self()->getCallingUid(); mUid = IPCThreadState::self()->getCallingUid(); } else { } else { Loading Loading @@ -755,7 +752,11 @@ void MediaCodec::statsBufferSent(int64_t presentationUs) { return; return; } } scheduleBatteryCheckerIfNeeded(); if (mBatteryChecker != nullptr) { mBatteryChecker->onCodecActivity([this] () { addResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1); }); } const int64_t nowNs = systemTime(SYSTEM_TIME_MONOTONIC); const int64_t nowNs = systemTime(SYSTEM_TIME_MONOTONIC); BufferFlightTiming_t startdata = { presentationUs, nowNs }; BufferFlightTiming_t startdata = { presentationUs, nowNs }; Loading Loading @@ -791,7 +792,11 @@ void MediaCodec::statsBufferReceived(int64_t presentationUs) { return; return; } } scheduleBatteryCheckerIfNeeded(); if (mBatteryChecker != nullptr) { mBatteryChecker->onCodecActivity([this] () { addResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1); }); } BufferFlightTiming_t startdata; BufferFlightTiming_t startdata; bool valid = false; bool valid = false; Loading Loading @@ -981,6 +986,10 @@ status_t MediaCodec::init(const AString &name) { mAnalyticsItem->setCString(kCodecMode, mIsVideo ? kCodecModeVideo : kCodecModeAudio); mAnalyticsItem->setCString(kCodecMode, mIsVideo ? kCodecModeVideo : kCodecModeAudio); } } if (mIsVideo) { mBatteryChecker = new BatteryChecker(new AMessage(kWhatCheckBatteryStats, this)); } status_t err; status_t err; Vector<MediaResource> resources; Vector<MediaResource> resources; MediaResource::Type type = MediaResource::Type type = Loading Loading @@ -1706,19 +1715,27 @@ void MediaCodec::requestCpuBoostIfNeeded() { } } } } void MediaCodec::scheduleBatteryCheckerIfNeeded() { BatteryChecker::BatteryChecker(const sp<AMessage> &msg, int64_t timeoutUs) if (!mIsVideo || !isExecuting()) { : 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 // ignore if not executing return; return; } } if (!mBatteryStatNotified) { if (!mBatteryStatNotified) { addResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1); batteryOnCb(); mBatteryStatNotified = true; mBatteryStatNotified = true; sp<AMessage> msg = new AMessage(kWhatCheckBatteryStats, this); sp<AMessage> msg = mBatteryCheckerMsg->dup(); msg->setInt32("generation", mBatteryCheckerGeneration); msg->setInt32("generation", mBatteryCheckerGeneration); // post checker and clear last activity time // post checker and clear last activity time msg->post(kBatteryStatsTimeoutUs); msg->post(mTimeoutUs); mLastActivityTimeUs = -1ll; mLastActivityTimeUs = -1ll; } else { } else { // update last activity time // 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 // ignore if this checker already expired because the client resource was removed int32_t generation; int32_t generation; if (!msg->findInt32("generation", &generation) if (!msg->findInt32("generation", &generation) Loading @@ -1736,15 +1754,20 @@ void MediaCodec::onBatteryChecker(const sp<AMessage> &msg) { if (mLastActivityTimeUs < 0ll) { if (mLastActivityTimeUs < 0ll) { // timed out inactive, do not repost checker // timed out inactive, do not repost checker removeResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1); batteryOffCb(); mBatteryStatNotified = false; mBatteryStatNotified = false; } else { } else { // repost checker and clear last activity time // repost checker and clear last activity time msg->post(kBatteryStatsTimeoutUs + mLastActivityTimeUs - ALooper::GetNowUs()); msg->post(mTimeoutUs + mLastActivityTimeUs - ALooper::GetNowUs()); mLastActivityTimeUs = -1ll; mLastActivityTimeUs = -1ll; } } } } void BatteryChecker::onClientRemoved() { mBatteryStatNotified = false; mBatteryCheckerGeneration++; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// void MediaCodec::cancelPendingDequeueOperations() { void MediaCodec::cancelPendingDequeueOperations() { Loading Loading @@ -2382,8 +2405,10 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { mFlags &= ~kFlagIsComponentAllocated; mFlags &= ~kFlagIsComponentAllocated; // off since we're removing all resources including the battery on // off since we're removing all resources including the battery on mBatteryStatNotified = false; if (mBatteryChecker != nullptr) { mBatteryCheckerGeneration++; mBatteryChecker->onClientRemoved(); } mResourceManagerService->removeClient(getId(mResourceManagerClient)); mResourceManagerService->removeClient(getId(mResourceManagerClient)); (new AMessage)->postReply(mReplyID); (new AMessage)->postReply(mReplyID); Loading Loading @@ -3097,7 +3122,11 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { case kWhatCheckBatteryStats: case kWhatCheckBatteryStats: { { onBatteryChecker(msg); if (mBatteryChecker != nullptr) { mBatteryChecker->onCheckBatteryTimer(msg, [this] () { removeResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1); }); } break; break; } } Loading Loading @@ -3197,6 +3226,10 @@ void MediaCodec::setState(State newState) { mState = newState; mState = newState; if (mBatteryChecker != nullptr) { mBatteryChecker->setExecuting(isExecuting()); } cancelPendingDequeueOperations(); cancelPendingDequeueOperations(); } } Loading media/libstagefright/TEST_MAPPING +3 −0 Original line number Original line Diff line number Diff line Loading @@ -7,6 +7,9 @@ "include-annotation": "android.platform.test.annotations.RequiresDevice" "include-annotation": "android.platform.test.annotations.RequiresDevice" } } ] ] }, { "name": "BatteryChecker_test" } } ] ] } } media/libstagefright/include/media/stagefright/BatteryChecker.h 0 → 100644 +47 −0 Original line number Original line 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 Original line Diff line number Diff line Loading @@ -36,6 +36,7 @@ struct ABuffer; struct AMessage; struct AMessage; struct AReplyToken; struct AReplyToken; struct AString; struct AString; struct BatteryChecker; class BufferChannelBase; class BufferChannelBase; struct CodecBase; struct CodecBase; class IBatteryStats; class IBatteryStats; Loading Loading @@ -463,11 +464,7 @@ private: Mutex mLatencyLock; Mutex mLatencyLock; int64_t mLatencyUnknown; // buffers for which we couldn't calculate latency int64_t mLatencyUnknown; // buffers for which we couldn't calculate latency int64_t mLastActivityTimeUs; sp<BatteryChecker> mBatteryChecker; bool mBatteryStatNotified; int32_t mBatteryCheckerGeneration; void onBatteryChecker(const sp<AMessage>& msg); void scheduleBatteryCheckerIfNeeded(); void statsBufferSent(int64_t presentationUs); void statsBufferSent(int64_t presentationUs); void statsBufferReceived(int64_t presentationUs); void statsBufferReceived(int64_t presentationUs); Loading media/libstagefright/tests/Android.bp +18 −0 Original line number Original line Diff line number Diff line Loading @@ -27,3 +27,21 @@ cc_test { "-Wall", "-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 Original line Diff line number Diff line Loading @@ -48,6 +48,7 @@ #include <media/stagefright/foundation/avc_utils.h> #include <media/stagefright/foundation/avc_utils.h> #include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/ACodec.h> #include <media/stagefright/ACodec.h> #include <media/stagefright/BatteryChecker.h> #include <media/stagefright/BufferProducerWrapper.h> #include <media/stagefright/BufferProducerWrapper.h> #include <media/stagefright/MediaCodec.h> #include <media/stagefright/MediaCodec.h> #include <media/stagefright/MediaCodecList.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 kMaxRetry = 2; static const int kMaxReclaimWaitTimeInUs = 500000; // 0.5s static const int kMaxReclaimWaitTimeInUs = 500000; // 0.5s static const int kNumBuffersAlign = 16; 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), mHaveInputSurface(false), mHavePendingInputBuffers(false), mHavePendingInputBuffers(false), mCpuBoostRequested(false), mCpuBoostRequested(false), mLatencyUnknown(0), mLatencyUnknown(0) { mLastActivityTimeUs(-1ll), mBatteryStatNotified(false), mBatteryCheckerGeneration(0) { if (uid == kNoUid) { if (uid == kNoUid) { mUid = IPCThreadState::self()->getCallingUid(); mUid = IPCThreadState::self()->getCallingUid(); } else { } else { Loading Loading @@ -755,7 +752,11 @@ void MediaCodec::statsBufferSent(int64_t presentationUs) { return; return; } } scheduleBatteryCheckerIfNeeded(); if (mBatteryChecker != nullptr) { mBatteryChecker->onCodecActivity([this] () { addResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1); }); } const int64_t nowNs = systemTime(SYSTEM_TIME_MONOTONIC); const int64_t nowNs = systemTime(SYSTEM_TIME_MONOTONIC); BufferFlightTiming_t startdata = { presentationUs, nowNs }; BufferFlightTiming_t startdata = { presentationUs, nowNs }; Loading Loading @@ -791,7 +792,11 @@ void MediaCodec::statsBufferReceived(int64_t presentationUs) { return; return; } } scheduleBatteryCheckerIfNeeded(); if (mBatteryChecker != nullptr) { mBatteryChecker->onCodecActivity([this] () { addResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1); }); } BufferFlightTiming_t startdata; BufferFlightTiming_t startdata; bool valid = false; bool valid = false; Loading Loading @@ -981,6 +986,10 @@ status_t MediaCodec::init(const AString &name) { mAnalyticsItem->setCString(kCodecMode, mIsVideo ? kCodecModeVideo : kCodecModeAudio); mAnalyticsItem->setCString(kCodecMode, mIsVideo ? kCodecModeVideo : kCodecModeAudio); } } if (mIsVideo) { mBatteryChecker = new BatteryChecker(new AMessage(kWhatCheckBatteryStats, this)); } status_t err; status_t err; Vector<MediaResource> resources; Vector<MediaResource> resources; MediaResource::Type type = MediaResource::Type type = Loading Loading @@ -1706,19 +1715,27 @@ void MediaCodec::requestCpuBoostIfNeeded() { } } } } void MediaCodec::scheduleBatteryCheckerIfNeeded() { BatteryChecker::BatteryChecker(const sp<AMessage> &msg, int64_t timeoutUs) if (!mIsVideo || !isExecuting()) { : 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 // ignore if not executing return; return; } } if (!mBatteryStatNotified) { if (!mBatteryStatNotified) { addResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1); batteryOnCb(); mBatteryStatNotified = true; mBatteryStatNotified = true; sp<AMessage> msg = new AMessage(kWhatCheckBatteryStats, this); sp<AMessage> msg = mBatteryCheckerMsg->dup(); msg->setInt32("generation", mBatteryCheckerGeneration); msg->setInt32("generation", mBatteryCheckerGeneration); // post checker and clear last activity time // post checker and clear last activity time msg->post(kBatteryStatsTimeoutUs); msg->post(mTimeoutUs); mLastActivityTimeUs = -1ll; mLastActivityTimeUs = -1ll; } else { } else { // update last activity time // 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 // ignore if this checker already expired because the client resource was removed int32_t generation; int32_t generation; if (!msg->findInt32("generation", &generation) if (!msg->findInt32("generation", &generation) Loading @@ -1736,15 +1754,20 @@ void MediaCodec::onBatteryChecker(const sp<AMessage> &msg) { if (mLastActivityTimeUs < 0ll) { if (mLastActivityTimeUs < 0ll) { // timed out inactive, do not repost checker // timed out inactive, do not repost checker removeResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1); batteryOffCb(); mBatteryStatNotified = false; mBatteryStatNotified = false; } else { } else { // repost checker and clear last activity time // repost checker and clear last activity time msg->post(kBatteryStatsTimeoutUs + mLastActivityTimeUs - ALooper::GetNowUs()); msg->post(mTimeoutUs + mLastActivityTimeUs - ALooper::GetNowUs()); mLastActivityTimeUs = -1ll; mLastActivityTimeUs = -1ll; } } } } void BatteryChecker::onClientRemoved() { mBatteryStatNotified = false; mBatteryCheckerGeneration++; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// void MediaCodec::cancelPendingDequeueOperations() { void MediaCodec::cancelPendingDequeueOperations() { Loading Loading @@ -2382,8 +2405,10 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { mFlags &= ~kFlagIsComponentAllocated; mFlags &= ~kFlagIsComponentAllocated; // off since we're removing all resources including the battery on // off since we're removing all resources including the battery on mBatteryStatNotified = false; if (mBatteryChecker != nullptr) { mBatteryCheckerGeneration++; mBatteryChecker->onClientRemoved(); } mResourceManagerService->removeClient(getId(mResourceManagerClient)); mResourceManagerService->removeClient(getId(mResourceManagerClient)); (new AMessage)->postReply(mReplyID); (new AMessage)->postReply(mReplyID); Loading Loading @@ -3097,7 +3122,11 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { case kWhatCheckBatteryStats: case kWhatCheckBatteryStats: { { onBatteryChecker(msg); if (mBatteryChecker != nullptr) { mBatteryChecker->onCheckBatteryTimer(msg, [this] () { removeResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1); }); } break; break; } } Loading Loading @@ -3197,6 +3226,10 @@ void MediaCodec::setState(State newState) { mState = newState; mState = newState; if (mBatteryChecker != nullptr) { mBatteryChecker->setExecuting(isExecuting()); } cancelPendingDequeueOperations(); cancelPendingDequeueOperations(); } } Loading
media/libstagefright/TEST_MAPPING +3 −0 Original line number Original line Diff line number Diff line Loading @@ -7,6 +7,9 @@ "include-annotation": "android.platform.test.annotations.RequiresDevice" "include-annotation": "android.platform.test.annotations.RequiresDevice" } } ] ] }, { "name": "BatteryChecker_test" } } ] ] } }
media/libstagefright/include/media/stagefright/BatteryChecker.h 0 → 100644 +47 −0 Original line number Original line 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 Original line Diff line number Diff line Loading @@ -36,6 +36,7 @@ struct ABuffer; struct AMessage; struct AMessage; struct AReplyToken; struct AReplyToken; struct AString; struct AString; struct BatteryChecker; class BufferChannelBase; class BufferChannelBase; struct CodecBase; struct CodecBase; class IBatteryStats; class IBatteryStats; Loading Loading @@ -463,11 +464,7 @@ private: Mutex mLatencyLock; Mutex mLatencyLock; int64_t mLatencyUnknown; // buffers for which we couldn't calculate latency int64_t mLatencyUnknown; // buffers for which we couldn't calculate latency int64_t mLastActivityTimeUs; sp<BatteryChecker> mBatteryChecker; bool mBatteryStatNotified; int32_t mBatteryCheckerGeneration; void onBatteryChecker(const sp<AMessage>& msg); void scheduleBatteryCheckerIfNeeded(); void statsBufferSent(int64_t presentationUs); void statsBufferSent(int64_t presentationUs); void statsBufferReceived(int64_t presentationUs); void statsBufferReceived(int64_t presentationUs); Loading
media/libstagefright/tests/Android.bp +18 −0 Original line number Original line Diff line number Diff line Loading @@ -27,3 +27,21 @@ cc_test { "-Wall", "-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