Merge "Support even more .avi files with .mp3 content not aligned to chunk boundaries"
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 34f0a64..a126e83 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -133,6 +133,39 @@
     }
 }
 
+static void dumpSource(const sp<MediaSource> &source, const String8 &filename) {
+    FILE *out = fopen(filename.string(), "wb");
+
+    CHECK_EQ((status_t)OK, source->start());
+
+    status_t err;
+    for (;;) {
+        MediaBuffer *mbuf;
+        err = source->read(&mbuf);
+
+        if (err == INFO_FORMAT_CHANGED) {
+            continue;
+        } else if (err != OK) {
+            break;
+        }
+
+        CHECK_EQ(
+                fwrite((const uint8_t *)mbuf->data() + mbuf->range_offset(),
+                       1,
+                       mbuf->range_length(),
+                       out),
+                (ssize_t)mbuf->range_length());
+
+        mbuf->release();
+        mbuf = NULL;
+    }
+
+    CHECK_EQ((status_t)OK, source->stop());
+
+    fclose(out);
+    out = NULL;
+}
+
 static void playSource(OMXClient *client, sp<MediaSource> &source) {
     sp<MetaData> meta = source->getFormat();
 
@@ -578,6 +611,7 @@
                     "(video only)\n");
     fprintf(stderr, "       -S allocate buffers from a surface\n");
     fprintf(stderr, "       -T allocate buffers from a surface texture\n");
+    fprintf(stderr, "       -d(ump) filename (raw stream data to a file)\n");
 }
 
 int main(int argc, char **argv) {
@@ -590,6 +624,8 @@
     bool seekTest = false;
     bool useSurfaceAlloc = false;
     bool useSurfaceTexAlloc = false;
+    bool dumpStream = false;
+    String8 dumpStreamFilename;
     gNumRepetitions = 1;
     gMaxNumFrames = 0;
     gReproduceBug = -1;
@@ -604,7 +640,7 @@
     sp<LiveSession> liveSession;
 
     int res;
-    while ((res = getopt(argc, argv, "han:lm:b:ptsrow:kxST")) >= 0) {
+    while ((res = getopt(argc, argv, "han:lm:b:ptsrow:kxSTd:")) >= 0) {
         switch (res) {
             case 'a':
             {
@@ -612,6 +648,13 @@
                 break;
             }
 
+            case 'd':
+            {
+                dumpStream = true;
+                dumpStreamFilename.setTo(optarg);
+                break;
+            }
+
             case 'l':
             {
                 listComponents = true;
@@ -1062,6 +1105,8 @@
 
         if (gWriteMP4) {
             writeSourcesToMP4(mediaSources, syncInfoPresent);
+        } else if (dumpStream) {
+            dumpSource(mediaSource, dumpStreamFilename);
         } else if (seekTest) {
             performSeekTest(mediaSource);
         } else {
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index 4a4bcfb..a520a6a 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -317,18 +317,13 @@
     // recalculate exposure values). Changing exposure compensation
     // settings will still affect the exposure settings while
     // auto-exposure is locked. Stopping preview or taking a still
-    // image will release the lock. However, the lock can be
-    // re-enabled prior to preview being re-started, to keep the
-    // exposure values from the previous lock. In conjunction with
+    // image will not change the lock. In conjunction with
     // exposure compensation, this allows for capturing multi-exposure
     // brackets with known relative exposure values. Locking
     // auto-exposure after open but before the first call to
     // startPreview may result in severely over- or under-exposed
-    // images.  The driver may independently enable the AE lock after
-    // auto-focus completes. If it does so, this key must have its
-    // value updated to reflect the lock's existence. Applications are
-    // free to release such a lock, to re-enable AE without restarting
-    // preview.
+    // images.  The driver will not change the AE lock after
+    // auto-focus completes.
     static const char KEY_AUTO_EXPOSURE_LOCK[];
     // Whether locking the auto-exposure is supported. "true" means it is, and
     // "false" or this key not existing means it is not supported.
@@ -339,18 +334,13 @@
     // change white balance values. If auto-white balance is already
     // locked, setting this to true again has no effect (the driver
     // will not recalculate white balance values). Stopping preview or
-    // taking a still image will release the lock. However, the lock
-    // can be re-enabled prior to preview being re-started, to keep
-    // the white balance values from the previous lock. In conjunction
+    // taking a still image will not change the lock. In conjunction
     // with exposure compensation, this allows for capturing
     // multi-exposure brackets with fixed white balance. Locking
     // auto-white balance after open but before the first call to
     // startPreview may result in severely incorrect color.  The
-    // driver may independently enable the AWB lock after auto-focus
-    // completes. If it does so, this key must have its value updated
-    // to reflect the lock's existence. Applications are free to
-    // release such a lock, to re-enable AWB without restarting
-    // preview.
+    // driver will not change the AWB lock after auto-focus
+    // completes.
     static const char KEY_AUTO_WHITEBALANCE_LOCK[];
     // Whether locking the auto-white balance is supported. "true"
     // means it is, and "false" or this key not existing means it is
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index 306f1f6..2b27ee2 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -764,8 +764,8 @@
     // If the loop was exited as a result of stopping the recording,
     // it is OK
     if (mStopped) {
-        LOGV("Read: SurfaceMediaSource is stopped. Returning NO_INIT;");
-        return NO_INIT;
+        LOGV("Read: SurfaceMediaSource is stopped. Returning ERROR_END_OF_STREAM.");
+        return ERROR_END_OF_STREAM;
     }
 
     // Update the current buffer info
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index a58f64c..88a05b2 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -7440,12 +7440,21 @@
     }
 }
 
+
+// The volume effect is used for automated tests only
+#ifndef OPENSL_ES_H_
+static const effect_uuid_t SL_IID_VOLUME_ = { 0x09e8ede0, 0xddde, 0x11db, 0xb4f6,
+                                            { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+const effect_uuid_t * const SL_IID_VOLUME = &SL_IID_VOLUME_;
+#endif //OPENSL_ES_H_
+
 bool AudioFlinger::EffectChain::isEffectEligibleForSuspend(const effect_descriptor_t& desc)
 {
     // auxiliary effects and visualizer are never suspended on output mix
     if ((mSessionId == AUDIO_SESSION_OUTPUT_MIX) &&
         (((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) ||
-         (memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0))) {
+         (memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) ||
+         (memcmp(&desc.type, SL_IID_VOLUME, sizeof(effect_uuid_t)) == 0))) {
         return false;
     }
     return true;