OSDN Git Service

Adapt frame rate instead of keeping that constant and tweaking bitrate
authorAndreas Huber <andih@google.com>
Tue, 26 Mar 2013 20:52:43 +0000 (13:52 -0700)
committerAndreas Huber <andih@google.com>
Tue, 26 Mar 2013 21:51:36 +0000 (14:51 -0700)
Change-Id: I889abbbe1237e1a8fdd7135cdc91a2e9728ff39b

media/libstagefright/wifi-display/source/Converter.cpp
media/libstagefright/wifi-display/source/Converter.h
media/libstagefright/wifi-display/source/PlaybackSession.cpp
media/libstagefright/wifi-display/source/RepeaterSource.cpp
media/libstagefright/wifi-display/source/RepeaterSource.h

index d41e1e6..0a8462c 100644 (file)
@@ -135,7 +135,9 @@ bool Converter::needToManuallyPrependSPSPPS() const {
     return mNeedToManuallyPrependSPSPPS;
 }
 
-static int32_t getBitrate(const char *propName, int32_t defaultValue) {
+// static
+int32_t Converter::GetInt32Property(
+        const char *propName, int32_t defaultValue) {
     char val[PROPERTY_VALUE_MAX];
     if (property_get(propName, val, NULL)) {
         char *end;
@@ -185,8 +187,8 @@ status_t Converter::initEncoder() {
 
     mOutputFormat->setString("mime", outputMIME.c_str());
 
-    int32_t audioBitrate = getBitrate("media.wfd.audio-bitrate", 128000);
-    int32_t videoBitrate = getBitrate("media.wfd.video-bitrate", 5000000);
+    int32_t audioBitrate = GetInt32Property("media.wfd.audio-bitrate", 128000);
+    int32_t videoBitrate = GetInt32Property("media.wfd.video-bitrate", 5000000);
     mPrevVideoBitrate = videoBitrate;
 
     ALOGI("using audio bitrate of %d bps, video bitrate of %d bps",
@@ -622,20 +624,6 @@ status_t Converter::feedEncoderInputBuffers() {
 }
 
 status_t Converter::doMoreWork() {
-#if 0
-    if (mIsVideo) {
-        int32_t videoBitrate = getBitrate("media.wfd.video-bitrate", 5000000);
-        if (videoBitrate != mPrevVideoBitrate) {
-            sp<AMessage> params = new AMessage;
-
-            params->setInt32("videoBitrate", videoBitrate);
-            mEncoder->setParameters(params);
-
-            mPrevVideoBitrate = videoBitrate;
-        }
-    }
-#endif
-
     status_t err;
 
     for (;;) {
index 538f10a..ba297c4 100644 (file)
@@ -73,6 +73,8 @@ struct Converter : public AHandler {
     int32_t getVideoBitrate() const;
     void setVideoBitrate(int32_t bitrate);
 
+    static int32_t GetInt32Property(const char *propName, int32_t defaultValue);
+
 protected:
     virtual ~Converter();
     virtual void onMessageReceived(const sp<AMessage> &msg);
index 68aa9cb..715d0b5 100644 (file)
@@ -27,6 +27,7 @@
 #include "WifiDisplaySource.h"
 
 #include <binder/IServiceManager.h>
+#include <cutils/properties.h>
 #include <media/IHDCP.h>
 #include <media/stagefright/foundation/ABitReader.h>
 #include <media/stagefright/foundation/ABuffer.h>
@@ -66,6 +67,7 @@ struct WifiDisplaySource::PlaybackSession::Track : public AHandler {
     bool isAudio() const;
 
     const sp<Converter> &converter() const;
+    const sp<RepeaterSource> &repeaterSource() const;
 
     ssize_t mediaSenderTrackIndex() const;
     void setMediaSenderTrackIndex(size_t index);
@@ -171,6 +173,11 @@ const sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() cons
     return mConverter;
 }
 
+const sp<RepeaterSource> &
+WifiDisplaySource::PlaybackSession::Track::repeaterSource() const {
+    return mRepeaterSource;
+}
+
 ssize_t WifiDisplaySource::PlaybackSession::Track::mediaSenderTrackIndex() const {
     CHECK_GE(mMediaSenderTrackIndex, 0);
     return mMediaSenderTrackIndex;
@@ -663,27 +670,67 @@ void WifiDisplaySource::PlaybackSession::onSinkFeedback(const sp<AMessage> &msg)
     if (mVideoTrackIndex >= 0) {
         const sp<Track> &videoTrack = mTracks.valueFor(mVideoTrackIndex);
         sp<Converter> converter = videoTrack->converter();
-        if (converter != NULL) {
-            int32_t videoBitrate = converter->getVideoBitrate();
 
-            if (avgLatencyUs > 300000ll) {
-                videoBitrate *= 0.6;
+        if (converter != NULL) {
+            int32_t videoBitrate =
+                Converter::GetInt32Property("media.wfd.video-bitrate", -1);
+
+            char val[PROPERTY_VALUE_MAX];
+            if (videoBitrate < 0
+                    && property_get("media.wfd.video-bitrate", val, NULL)
+                    && !strcasecmp("adaptive", val)) {
+                videoBitrate = converter->getVideoBitrate();
+
+                if (avgLatencyUs > 300000ll) {
+                    videoBitrate *= 0.6;
+                } else if (avgLatencyUs < 100000ll) {
+                    videoBitrate *= 1.1;
+                }
+            }
 
+            if (videoBitrate > 0) {
                 if (videoBitrate < 500000) {
-                    videoBitrate = 500000;  // cap at 500kbit/sec
+                    videoBitrate = 500000;
+                } else if (videoBitrate > 10000000) {
+                    videoBitrate = 10000000;
+                }
+
+                if (videoBitrate != converter->getVideoBitrate()) {
+                    ALOGI("setting video bitrate to %d bps", videoBitrate);
+
+                    converter->setVideoBitrate(videoBitrate);
                 }
-            } else if (avgLatencyUs < 100000ll) {
-                videoBitrate *= 1.1;
+            }
+        }
+
+        sp<RepeaterSource> repeaterSource = videoTrack->repeaterSource();
+        if (repeaterSource != NULL) {
+            double rateHz =
+                Converter::GetInt32Property(
+                        "media.wfd.video-framerate", -1);
 
-                if (videoBitrate > 10000000) {
-                    videoBitrate = 10000000;  // cap at 10Mbit/sec
+            if (rateHz < 0.0) {
+                rateHz = repeaterSource->getFrameRate();
+
+                if (avgLatencyUs > 300000ll) {
+                    rateHz *= 0.9;
+                } else if (avgLatencyUs < 200000ll) {
+                    rateHz *= 1.1;
                 }
             }
 
-            if (videoBitrate != converter->getVideoBitrate()) {
-                ALOGI("setting video bitrate to %d bps", videoBitrate);
+            if (rateHz > 0) {
+                if (rateHz < 5.0) {
+                    rateHz = 5.0;
+                } else if (rateHz > 30.0) {
+                    rateHz = 30.0;
+                }
+
+                if (rateHz != repeaterSource->getFrameRate()) {
+                    ALOGI("setting frame rate to %.2f Hz", rateHz);
 
-                converter->setVideoBitrate(videoBitrate);
+                    repeaterSource->setFrameRate(rateHz);
+                }
             }
         }
     }
index 72be927..cc8dee3 100644 (file)
@@ -27,6 +27,25 @@ RepeaterSource::~RepeaterSource() {
     CHECK(!mStarted);
 }
 
+double RepeaterSource::getFrameRate() const {
+    return mRateHz;
+}
+
+void RepeaterSource::setFrameRate(double rateHz) {
+    Mutex::Autolock autoLock(mLock);
+
+    if (rateHz == mRateHz) {
+        return;
+    }
+
+    if (mStartTimeUs >= 0ll) {
+        int64_t nextTimeUs = mStartTimeUs + (mFrameCount * 1000000ll) / mRateHz;
+        mStartTimeUs = nextTimeUs;
+        mFrameCount = 0;
+    }
+    mRateHz = rateHz;
+}
+
 status_t RepeaterSource::start(MetaData *params) {
     CHECK(!mStarted);
 
index 146af32..8d414fd 100644 (file)
@@ -28,6 +28,9 @@ struct RepeaterSource : public MediaSource {
     // send updates in a while, this is its wakeup call.
     void wakeUp();
 
+    double getFrameRate() const;
+    void setFrameRate(double rateHz);
+
 protected:
     virtual ~RepeaterSource();