Merge "update battery stats for video/audio" into lmp-dev
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index 3f7508b..26a0963 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -30,6 +30,7 @@
struct AString;
struct CodecBase;
struct ICrypto;
+struct IBatteryStats;
struct SoftwareRenderer;
struct Surface;
@@ -51,6 +52,8 @@
CB_OUTPUT_FORMAT_CHANGED = 4,
};
+ struct BatteryNotifier;
+
static sp<MediaCodec> CreateByType(
const sp<ALooper> &looper, const char *mime, bool encoder);
@@ -225,6 +228,9 @@
sp<AMessage> mInputFormat;
sp<AMessage> mCallback;
+ bool mBatteryStatNotified;
+ bool mIsVideo;
+
// initial create parameters
AString mInitName;
bool mInitNameIsType;
@@ -294,6 +300,7 @@
status_t onSetParameters(const sp<AMessage> ¶ms);
status_t amendOutputFormatWithCodecSpecificData(const sp<ABuffer> &buffer);
+ void updateBatteryStat();
DISALLOW_EVIL_CONSTRUCTORS(MediaCodec);
};
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 7a9cb0b..15e062e 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -16,13 +16,13 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "MediaCodec"
-#include <utils/Log.h>
#include <inttypes.h>
-#include <media/stagefright/MediaCodec.h>
-
+#include "include/avc_utils.h"
#include "include/SoftwareRenderer.h"
+#include <binder/IBatteryStats.h>
+#include <binder/IServiceManager.h>
#include <gui/Surface.h>
#include <media/ICrypto.h>
#include <media/stagefright/foundation/ABuffer.h>
@@ -32,16 +32,85 @@
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/ACodec.h>
#include <media/stagefright/BufferProducerWrapper.h>
+#include <media/stagefright/MediaCodec.h>
#include <media/stagefright/MediaCodecList.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/NativeWindowWrapper.h>
-
-#include "include/avc_utils.h"
+#include <private/android_filesystem_config.h>
+#include <utils/Log.h>
+#include <utils/Singleton.h>
namespace android {
+struct MediaCodec::BatteryNotifier : public Singleton<BatteryNotifier> {
+ BatteryNotifier();
+
+ void noteStartVideo();
+ void noteStopVideo();
+ void noteStartAudio();
+ void noteStopAudio();
+
+private:
+ int32_t mVideoRefCount;
+ int32_t mAudioRefCount;
+ sp<IBatteryStats> mBatteryStatService;
+};
+
+ANDROID_SINGLETON_STATIC_INSTANCE(MediaCodec::BatteryNotifier)
+
+MediaCodec::BatteryNotifier::BatteryNotifier() :
+ mVideoRefCount(0),
+ mAudioRefCount(0) {
+ // get battery service
+ const sp<IServiceManager> sm(defaultServiceManager());
+ if (sm != NULL) {
+ const String16 name("batterystats");
+ mBatteryStatService = interface_cast<IBatteryStats>(sm->getService(name));
+ if (mBatteryStatService == NULL) {
+ ALOGE("batterystats service unavailable!");
+ }
+ }
+}
+
+void MediaCodec::BatteryNotifier::noteStartVideo() {
+ if (mVideoRefCount == 0 && mBatteryStatService != NULL) {
+ mBatteryStatService->noteStartVideo(AID_MEDIA);
+ }
+ mVideoRefCount++;
+}
+
+void MediaCodec::BatteryNotifier::noteStopVideo() {
+ if (mVideoRefCount == 0) {
+ ALOGW("BatteryNotifier::noteStop(): video refcount is broken!");
+ return;
+ }
+
+ mVideoRefCount--;
+ if (mVideoRefCount == 0 && mBatteryStatService != NULL) {
+ mBatteryStatService->noteStopVideo(AID_MEDIA);
+ }
+}
+
+void MediaCodec::BatteryNotifier::noteStartAudio() {
+ if (mAudioRefCount == 0 && mBatteryStatService != NULL) {
+ mBatteryStatService->noteStartAudio(AID_MEDIA);
+ }
+ mAudioRefCount++;
+}
+
+void MediaCodec::BatteryNotifier::noteStopAudio() {
+ if (mAudioRefCount == 0) {
+ ALOGW("BatteryNotifier::noteStop(): audio refcount is broken!");
+ return;
+ }
+
+ mAudioRefCount--;
+ if (mAudioRefCount == 0 && mBatteryStatService != NULL) {
+ mBatteryStatService->noteStopAudio(AID_MEDIA);
+ }
+}
// static
sp<MediaCodec> MediaCodec::CreateByType(
const sp<ALooper> &looper, const char *mime, bool encoder) {
@@ -71,6 +140,8 @@
mReplyID(0),
mFlags(0),
mSoftRenderer(NULL),
+ mBatteryStatNotified(false),
+ mIsVideo(false),
mDequeueInputTimeoutGeneration(0),
mDequeueInputReplyID(0),
mDequeueOutputTimeoutGeneration(0),
@@ -756,7 +827,6 @@
case CodecBase::kWhatComponentConfigured:
{
CHECK_EQ(mState, CONFIGURING);
- setState(CONFIGURED);
// reset input surface flag
mHaveInputSurface = false;
@@ -764,6 +834,7 @@
CHECK(msg->findMessage("input-format", &mInputFormat));
CHECK(msg->findMessage("output-format", &mOutputFormat));
+ setState(CONFIGURED);
(new AMessage)->postReply(mReplyID);
break;
}
@@ -1620,6 +1691,8 @@
mState = newState;
cancelPendingDequeueOperations();
+
+ updateBatteryStat();
}
void MediaCodec::returnBuffersToCodec() {
@@ -2054,4 +2127,34 @@
return OK;
}
+void MediaCodec::updateBatteryStat() {
+ if (mState == CONFIGURED && !mBatteryStatNotified) {
+ AString mime;
+ CHECK(mOutputFormat != NULL &&
+ mOutputFormat->findString("mime", &mime));
+
+ mIsVideo = mime.startsWithIgnoreCase("video/");
+
+ BatteryNotifier& notifier(BatteryNotifier::getInstance());
+
+ if (mIsVideo) {
+ notifier.noteStartVideo();
+ } else {
+ notifier.noteStartAudio();
+ }
+
+ mBatteryStatNotified = true;
+ } else if (mState == UNINITIALIZED && mBatteryStatNotified) {
+ BatteryNotifier& notifier(BatteryNotifier::getInstance());
+
+ if (mIsVideo) {
+ notifier.noteStopVideo();
+ } else {
+ notifier.noteStopAudio();
+ }
+
+ mBatteryStatNotified = false;
+ }
+}
+
} // namespace android