Support for auxiliary video parameters.

Added support for passing width, height and video bitrate
for the auxiliary video.
Also setting encoder level depending on the video size and bitrate.

Change-Id: I4a90046853f67287c3e7e6babc75b4827f0c3e73
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index bbbf45c..f1b8334 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -24,6 +24,7 @@
 #include <media/stagefright/AudioSource.h>
 #include <media/stagefright/AMRWriter.h>
 #include <media/stagefright/CameraSource.h>
+#include <media/stagefright/VideoSourceDownSampler.h>
 #include <media/stagefright/CameraSourceTimeLapse.h>
 #include <media/stagefright/MediaSourceSplitter.h>
 #include <media/stagefright/MPEG4Writer.h>
@@ -532,6 +533,42 @@
     return OK;
 }
 
+status_t StagefrightRecorder::setParamAuxVideoWidth(int32_t width) {
+    LOGV("setParamAuxVideoWidth : %d", width);
+
+    if (width <= 0) {
+        LOGE("Width (%d) is not positive", width);
+        return BAD_VALUE;
+    }
+
+    mAuxVideoWidth = width;
+    return OK;
+}
+
+status_t StagefrightRecorder::setParamAuxVideoHeight(int32_t height) {
+    LOGV("setParamAuxVideoHeight : %d", height);
+
+    if (height <= 0) {
+        LOGE("Height (%d) is not positive", height);
+        return BAD_VALUE;
+    }
+
+    mAuxVideoHeight = height;
+    return OK;
+}
+
+status_t StagefrightRecorder::setParamAuxVideoEncodingBitRate(int32_t bitRate) {
+    LOGV("StagefrightRecorder::setParamAuxVideoEncodingBitRate: %d", bitRate);
+
+    if (bitRate <= 0) {
+        LOGE("Invalid video encoding bit rate: %d", bitRate);
+        return BAD_VALUE;
+    }
+
+    mAuxVideoBitRate = bitRate;
+    return OK;
+}
+
 status_t StagefrightRecorder::setParameter(
         const String8 &key, const String8 &value) {
     LOGV("setParameter: key (%s) => value (%s)", key.string(), value.string());
@@ -631,6 +668,21 @@
             return setParamTimeBetweenTimeLapseFrameCapture(
                     1000LL * timeBetweenTimeLapseFrameCaptureMs);
         }
+    } else if (key == "video-aux-param-width") {
+        int32_t auxWidth;
+        if (safe_strtoi32(value.string(), &auxWidth)) {
+            return setParamAuxVideoWidth(auxWidth);
+        }
+    } else if (key == "video-aux-param-height") {
+        int32_t auxHeight;
+        if (safe_strtoi32(value.string(), &auxHeight)) {
+            return setParamAuxVideoHeight(auxHeight);
+        }
+    } else if (key == "video-aux-param-encoding-bitrate") {
+        int32_t auxVideoBitRate;
+        if (safe_strtoi32(value.string(), &auxVideoBitRate)) {
+            return setParamAuxVideoEncodingBitRate(auxVideoBitRate);
+        }
     } else {
         LOGE("setParameter: failed to find key %s", key.string());
     }
@@ -1079,6 +1131,13 @@
     }
     if (mVideoEncoderLevel != -1) {
         enc_meta->setInt32(kKeyVideoLevel, mVideoEncoderLevel);
+    } else if (mCaptureTimeLapse) {
+        // Check if we are using high resolution and/or high bitrate and
+        // set appropriate level for the software AVCEncoder.
+        if ((width * height >= 921600) // 720p
+                || (videoBitRate >= 20000000)) {
+            enc_meta->setInt32(kKeyVideoLevel, 50);
+        }
     }
 
     OMXClient client;
@@ -1122,7 +1181,9 @@
 
 status_t StagefrightRecorder::setupMPEG4Recording(
         bool useSplitCameraSource,
-        int outputFd, int32_t audioBitRate, int32_t videoBitRate,
+        int outputFd,
+        int32_t videoWidth, int32_t videoHeight,
+        int32_t videoBitRate,
         int32_t *totalBitRate,
         sp<MediaWriter> *mediaWriter) {
     mediaWriter->clear();
@@ -1134,7 +1195,7 @@
     if (!mCaptureTimeLapse && (mAudioSource != AUDIO_SOURCE_LIST_END)) {
         err = setupAudioEncoder(writer);
         if (err != OK) return err;
-        *totalBitRate += audioBitRate;
+        *totalBitRate += mAudioBitRate;
     }
     if (mVideoSource == VIDEO_SOURCE_DEFAULT
             || mVideoSource == VIDEO_SOURCE_CAMERA) {
@@ -1148,6 +1209,13 @@
             err = setupCameraSource(&cameraSource);
             cameraMediaSource = cameraSource;
         }
+        if ((videoWidth != mVideoWidth) || (videoHeight != mVideoHeight)) {
+            // Use downsampling from the original source.
+            CHECK(videoWidth <= mVideoWidth);
+            CHECK(videoHeight <= mVideoHeight);
+            cameraMediaSource =
+                new VideoSourceDownSampler(cameraMediaSource, videoWidth, videoHeight);
+        }
         if (err != OK) {
             return err;
         }
@@ -1207,7 +1275,8 @@
 
     int32_t totalBitRate;
     status_t err = setupMPEG4Recording(mCaptureAuxVideo,
-            mOutputFd, mAudioBitRate, mVideoBitRate, &totalBitRate, &mWriter);
+            mOutputFd, mVideoWidth, mVideoHeight,
+            mVideoBitRate, &totalBitRate, &mWriter);
     if (err != OK) {
         return err;
     }
@@ -1230,7 +1299,8 @@
 
         int32_t totalBitrateAux;
         err = setupMPEG4Recording(mCaptureAuxVideo,
-                mOutputFdAux, mAudioBitRateAux, mVideoBitRateAux, &totalBitrateAux, &mWriterAux);
+                mOutputFdAux, mAuxVideoWidth, mAuxVideoHeight,
+                mAuxVideoBitRate, &totalBitrateAux, &mWriterAux);
         if (err != OK) {
             return err;
         }
@@ -1326,13 +1396,14 @@
     mVideoEncoder  = VIDEO_ENCODER_H263;
     mVideoWidth    = 176;
     mVideoHeight   = 144;
+    mAuxVideoWidth    = 176;
+    mAuxVideoHeight   = 144;
     mFrameRate     = 20;
     mVideoBitRate  = 192000;
-    mVideoBitRateAux = 20000000;
+    mAuxVideoBitRate = 192000;
     mSampleRate    = 8000;
     mAudioChannels = 1;
     mAudioBitRate  = 12200;
-    mAudioBitRateAux  = 12200;
     mInterleaveDurationUs = 0;
     mIFramesIntervalSec = 1;
     mAudioSourceNode = 0;
@@ -1414,8 +1485,6 @@
     result.append(buffer);
     snprintf(buffer, SIZE, "     Bit rate (bps): %d\n", mAudioBitRate);
     result.append(buffer);
-    snprintf(buffer, SIZE, "     Bit rate auxiliary (bps): %d\n", mAudioBitRateAux);
-    result.append(buffer);
     snprintf(buffer, SIZE, "     Sampling rate (hz): %d\n", mSampleRate);
     result.append(buffer);
     snprintf(buffer, SIZE, "     Number of channels: %d\n", mAudioChannels);
@@ -1440,11 +1509,13 @@
     result.append(buffer);
     snprintf(buffer, SIZE, "     Frame size (pixels): %dx%d\n", mVideoWidth, mVideoHeight);
     result.append(buffer);
+    snprintf(buffer, SIZE, "     Aux Frame size (pixels): %dx%d\n", mAuxVideoWidth, mAuxVideoHeight);
+    result.append(buffer);
     snprintf(buffer, SIZE, "     Frame rate (fps): %d\n", mFrameRate);
     result.append(buffer);
     snprintf(buffer, SIZE, "     Bit rate (bps): %d\n", mVideoBitRate);
     result.append(buffer);
-    snprintf(buffer, SIZE, "     Bit rate Auxiliary (bps): %d\n", mVideoBitRateAux);
+    snprintf(buffer, SIZE, "     Aux Bit rate (bps): %d\n", mAuxVideoBitRate);
     result.append(buffer);
     ::write(fd, result.string(), result.size());
     return OK;
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index d75a540..d50a393 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -79,9 +79,10 @@
     video_encoder mVideoEncoder;
     bool mUse64BitFileOffset;
     int32_t mVideoWidth, mVideoHeight;
+    int32_t mAuxVideoWidth, mAuxVideoHeight;
     int32_t mFrameRate;
-    int32_t mVideoBitRate, mVideoBitRateAux;
-    int32_t mAudioBitRate, mAudioBitRateAux;
+    int32_t mVideoBitRate, mAuxVideoBitRate;
+    int32_t mAudioBitRate;
     int32_t mAudioChannels;
     int32_t mSampleRate;
     int32_t mInterleaveDurationUs;
@@ -109,8 +110,10 @@
     MediaProfiles *mEncoderProfiles;
 
     status_t setupMPEG4Recording(
-        bool useAuxiliaryCameraSource,
-        int outputFd, int32_t audioBitRate, int32_t videoBitRate,
+        bool useSplitCameraSource,
+        int outputFd,
+        int32_t videoWidth, int32_t videoHeight,
+        int32_t videoBitRate,
         int32_t *totalBitRate,
         sp<MediaWriter> *mediaWriter);
     void setupMPEG4MetaData(int64_t startTimeUs, int32_t totalBitRate,
@@ -137,6 +140,9 @@
     status_t setParamTimeLapseEnable(int32_t timeLapseEnable);
     status_t setParamUseStillCameraForTimeLapse(int32_t useStillCamera);
     status_t setParamTimeBetweenTimeLapseFrameCapture(int64_t timeUs);
+    status_t setParamAuxVideoHeight(int32_t height);
+    status_t setParamAuxVideoWidth(int32_t width);
+    status_t setParamAuxVideoEncodingBitRate(int32_t bitRate);
     status_t setParamVideoEncodingBitRate(int32_t bitRate);
     status_t setParamVideoIFramesInterval(int32_t seconds);
     status_t setParamVideoEncoderProfile(int32_t profile);