Merge "Allow for dynamic reconfiguration of the video bitrate used"
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index df1c46b..317b6f0 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -54,6 +54,8 @@
     void signalResume();
     void initiateShutdown(bool keepComponentAllocated = false);
 
+    void signalSetParameters(const sp<AMessage> &msg);
+
     void initiateAllocateComponent(const sp<AMessage> &msg);
     void initiateConfigureComponent(const sp<AMessage> &msg);
     void initiateStart();
@@ -105,6 +107,7 @@
         kWhatConfigureComponent      = 'conf',
         kWhatStart                   = 'star',
         kWhatRequestIDRFrame         = 'ridr',
+        kWhatSetParameters           = 'setP',
     };
 
     enum {
@@ -270,6 +273,7 @@
             status_t internalError = UNKNOWN_ERROR);
 
     status_t requestIDRFrame();
+    status_t setParameters(const sp<AMessage> &params);
 
     DISALLOW_EVIL_CONSTRUCTORS(ACodec);
 };
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index 88aabf6..3f0d3b3 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -115,6 +115,8 @@
 
     status_t getName(AString *componentName) const;
 
+    status_t setParameters(const sp<AMessage> &params);
+
 protected:
     virtual ~MediaCodec();
     virtual void onMessageReceived(const sp<AMessage> &msg);
@@ -157,6 +159,7 @@
         kWhatRequestIDRFrame                = 'ridr',
         kWhatRequestActivityNotification    = 'racN',
         kWhatGetName                        = 'getN',
+        kWhatSetParameters                  = 'setP',
     };
 
     enum {
@@ -230,6 +233,8 @@
 
     void postActivityNotificationIfPossible();
 
+    status_t onSetParameters(const sp<AMessage> &params);
+
     DISALLOW_EVIL_CONSTRUCTORS(MediaCodec);
 };
 
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 7b27843..a6cc4eb 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -374,6 +374,12 @@
     msg->post();
 }
 
+void ACodec::signalSetParameters(const sp<AMessage> &params) {
+    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
+    msg->setMessage("params", params);
+    msg->post();
+}
+
 void ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
     msg->setWhat(kWhatAllocateComponent);
     msg->setTarget(id());
@@ -3550,6 +3556,23 @@
             break;
         }
 
+        case kWhatSetParameters:
+        {
+            sp<AMessage> params;
+            CHECK(msg->findMessage("params", &params));
+
+            status_t err = mCodec->setParameters(params);
+
+            sp<AMessage> reply;
+            if (msg->findMessage("reply", &reply)) {
+                reply->setInt32("err", err);
+                reply->post();
+            }
+
+            handled = true;
+            break;
+        }
+
         default:
             handled = BaseState::onMessageReceived(msg);
             break;
@@ -3558,6 +3581,31 @@
     return handled;
 }
 
+status_t ACodec::setParameters(const sp<AMessage> &params) {
+    int32_t videoBitrate;
+    if (params->findInt32("videoBitrate", &videoBitrate)) {
+        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
+        InitOMXParams(&configParams);
+        configParams.nPortIndex = kPortIndexOutput;
+        configParams.nEncodeBitrate = videoBitrate;
+
+        status_t err = mOMX->setConfig(
+                mNode,
+                OMX_IndexConfigVideoBitrate,
+                &configParams,
+                sizeof(configParams));
+
+        if (err != OK) {
+            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
+                   videoBitrate, err);
+
+            return err;
+        }
+    }
+
+    return OK;
+}
+
 bool ACodec::ExecutingState::onOMXEvent(
         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
     switch (event) {
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index cb8a651..77aceb7 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -1203,6 +1203,23 @@
             break;
         }
 
+        case kWhatSetParameters:
+        {
+            uint32_t replyID;
+            CHECK(msg->senderAwaitsResponse(&replyID));
+
+            sp<AMessage> params;
+            CHECK(msg->findMessage("params", &params));
+
+            status_t err = onSetParameters(params);
+
+            sp<AMessage> response = new AMessage;
+            response->setInt32("err", err);
+
+            response->postReply(replyID);
+            break;
+        }
+
         default:
             TRESPASS();
     }
@@ -1556,4 +1573,18 @@
     }
 }
 
+status_t MediaCodec::setParameters(const sp<AMessage> &params) {
+    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
+    msg->setMessage("params", params);
+
+    sp<AMessage> response;
+    return PostAndAwaitResponse(msg, &response);
+}
+
+status_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
+    mCodec->signalSetParameters(params);
+
+    return OK;
+}
+
 }  // namespace android
diff --git a/media/libstagefright/wifi-display/source/Converter.cpp b/media/libstagefright/wifi-display/source/Converter.cpp
index 5628dec..376b0df 100644
--- a/media/libstagefright/wifi-display/source/Converter.cpp
+++ b/media/libstagefright/wifi-display/source/Converter.cpp
@@ -54,6 +54,7 @@
       ,mFirstSilentFrameUs(-1ll)
       ,mInSilentMode(false)
 #endif
+      ,mPrevVideoBitrate(-1)
     {
     AString mime;
     CHECK(mInputFormat->findString("mime", &mime));
@@ -185,6 +186,7 @@
 
     int32_t audioBitrate = getBitrate("media.wfd.audio-bitrate", 128000);
     int32_t videoBitrate = getBitrate("media.wfd.video-bitrate", 5000000);
+    mPrevVideoBitrate = videoBitrate;
 
     ALOGI("using audio bitrate of %d bps, video bitrate of %d bps",
           audioBitrate, videoBitrate);
@@ -606,6 +608,18 @@
 }
 
 status_t Converter::doMoreWork() {
+    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;
+        }
+    }
+
     status_t err;
 
     for (;;) {
diff --git a/media/libstagefright/wifi-display/source/Converter.h b/media/libstagefright/wifi-display/source/Converter.h
index 3357d61..57802bd 100644
--- a/media/libstagefright/wifi-display/source/Converter.h
+++ b/media/libstagefright/wifi-display/source/Converter.h
@@ -100,6 +100,8 @@
 
     sp<ABuffer> mPartialAudioAU;
 
+    int32_t mPrevVideoBitrate;
+
     status_t initEncoder();
     void releaseEncoder();