Merge "audioflinger: changes for new audio devices enums" into jb-mr1-dev
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 7d49ef0..dc8e4a3 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -1665,15 +1665,26 @@
                     mLastCommentData.setTo((const char *)buffer + 8);
                     break;
             }
-            if (mLastCommentMean == "com.apple.iTunes"
-                    && mLastCommentName == "iTunSMPB"
-                    && mLastCommentData.length() != 0) {
-                int32_t delay, padding;
-                if (sscanf(mLastCommentData,
-                           " %*x %x %x %*x", &delay, &padding) == 2) {
-                    mLastTrack->meta->setInt32(kKeyEncoderDelay, delay);
-                    mLastTrack->meta->setInt32(kKeyEncoderPadding, padding);
+
+            // Once we have a set of mean/name/data info, go ahead and process
+            // it to see if its something we are interested in.  Whether or not
+            // were are interested in the specific tag, make sure to clear out
+            // the set so we can be ready to process another tuple should one
+            // show up later in the file.
+            if ((mLastCommentMean.length() != 0) &&
+                (mLastCommentName.length() != 0) &&
+                (mLastCommentData.length() != 0)) {
+
+                if (mLastCommentMean == "com.apple.iTunes"
+                        && mLastCommentName == "iTunSMPB") {
+                    int32_t delay, padding;
+                    if (sscanf(mLastCommentData,
+                               " %*x %x %x %*x", &delay, &padding) == 2) {
+                        mLastTrack->meta->setInt32(kKeyEncoderDelay, delay);
+                        mLastTrack->meta->setInt32(kKeyEncoderPadding, padding);
+                    }
                 }
+
                 mLastCommentMean.clear();
                 mLastCommentName.clear();
                 mLastCommentData.clear();
diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp
index 5400604..7abb405 100644
--- a/services/camera/libcameraservice/Camera2Client.cpp
+++ b/services/camera/libcameraservice/Camera2Client.cpp
@@ -156,6 +156,11 @@
     disconnect();
 
     mFrameProcessor->requestExit();
+    mCaptureSequencer->requestExit();
+    mJpegProcessor->requestExit();
+    mZslProcessor->requestExit();
+    mCallbackProcessor->requestExit();
+
     ALOGI("Camera %d: Closed", mCameraId);
 }
 
@@ -391,6 +396,8 @@
 
     mCallbackProcessor->deleteStream();
 
+    mZslProcessor->deleteStream();
+
     mDevice.clear();
     SharedParameters::Lock l(mParameters);
     l.mParameters.state = Parameters::DISCONNECTED;
@@ -639,7 +646,7 @@
             return res;
         }
     }
-    if (params.zslMode) {
+    if (params.zslMode && !params.recordingHint) {
         res = mZslProcessor->updateStream(params);
         if (res != OK) {
             ALOGE("%s: Camera %d: Unable to update ZSL stream: %s (%d)",
@@ -648,10 +655,45 @@
         }
     }
 
-    if (mPreviewRequest.entryCount() == 0) {
-        res = updatePreviewRequest(params);
+    CameraMetadata *request;
+    if (!params.recordingHint) {
+        if (mPreviewRequest.entryCount() == 0) {
+            res = updatePreviewRequest(params);
+            if (res != OK) {
+                ALOGE("%s: Camera %d: Unable to create preview request: %s (%d)",
+                        __FUNCTION__, mCameraId, strerror(-res), res);
+                return res;
+            }
+        }
+        request = &mPreviewRequest;
+    } else {
+        // With recording hint set, we're going to be operating under the
+        // assumption that the user will record video. To optimize recording
+        // startup time, create the necessary output streams for recording and
+        // video snapshot now if they don't already exist.
+        if (mRecordingRequest.entryCount() == 0) {
+            res = updateRecordingRequest(params);
+            if (res != OK) {
+                ALOGE("%s: Camera %d: Unable to create recording preview "
+                        "request: %s (%d)",
+                        __FUNCTION__, mCameraId, strerror(-res), res);
+                return res;
+            }
+        }
+        request = &mRecordingRequest;
+
+        res = updateRecordingStream(params);
         if (res != OK) {
-            ALOGE("%s: Camera %d: Unable to create preview request: %s (%d)",
+            ALOGE("%s: Camera %d: Unable to pre-configure recording "
+                    "stream: %s (%d)",
+                    __FUNCTION__, mCameraId, strerror(-res), res);
+            return res;
+        }
+
+        res = mJpegProcessor->updateStream(params);
+        if (res != OK) {
+            ALOGE("%s: Camera %d: Can't pre-configure still image "
+                    "stream: %s (%d)",
                     __FUNCTION__, mCameraId, strerror(-res), res);
             return res;
         }
@@ -663,11 +705,11 @@
     if (callbacksEnabled) {
         outputStreams.push(getCallbackStreamId());
     }
-    if (params.zslMode) {
+    if (params.zslMode && !params.recordingHint) {
         outputStreams.push(getZslStreamId());
     }
 
-    res = mPreviewRequest.update(
+    res = request->update(
         ANDROID_REQUEST_OUTPUT_STREAMS,
         outputStreams);
 
@@ -676,14 +718,14 @@
                 __FUNCTION__, mCameraId, strerror(-res), res);
         return res;
     }
-    res = mPreviewRequest.sort();
+    res = request->sort();
     if (res != OK) {
         ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
                 __FUNCTION__, mCameraId, strerror(-res), res);
         return res;
     }
 
-    res = mDevice->setStreamingRequest(mPreviewRequest);
+    res = mDevice->setStreamingRequest(*request);
     if (res != OK) {
         ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
                 "%s (%d)",
@@ -816,6 +858,8 @@
         return INVALID_OPERATION;
     }
 
+    mCameraService->playSound(CameraService::SOUND_RECORDING);
+
     res = updateRecordingStream(params);
     if (res != OK) {
         ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
@@ -910,19 +954,13 @@
             return;
     };
 
-    // Back to preview. Since record can only be reached through preview,
-    // all preview stream setup should be up to date.
-    res = mDevice->setStreamingRequest(mPreviewRequest);
+    mCameraService->playSound(CameraService::SOUND_RECORDING);
+
+    res = startPreviewL(l.mParameters, true);
     if (res != OK) {
-        ALOGE("%s: Camera %d: Unable to switch back to preview request: "
-                "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
-        return;
+        ALOGE("%s: Camera %d: Unable to return to preview",
+                __FUNCTION__, mCameraId);
     }
-
-    // TODO: Should recording heap be freed? Can't do it yet since requests
-    // could still be in flight.
-
-    l.mParameters.state = Parameters::PREVIEW;
 }
 
 bool Camera2Client::recordingEnabled() {
@@ -1448,6 +1486,10 @@
     return mDevice;
 }
 
+const sp<CameraService>& Camera2Client::getCameraService() {
+    return mCameraService;
+}
+
 camera2::SharedParameters& Camera2Client::getParameters() {
     return mParameters;
 }
@@ -1612,7 +1654,7 @@
 
 /** Utility methods */
 
-status_t Camera2Client::updateRequests(const Parameters &params) {
+status_t Camera2Client::updateRequests(Parameters &params) {
     status_t res;
 
     res = updatePreviewRequest(params);
@@ -1629,7 +1671,7 @@
     }
 
     if (params.state == Parameters::PREVIEW) {
-        res = mDevice->setStreamingRequest(mPreviewRequest);
+        res = startPreviewL(params, true);
         if (res != OK) {
             ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
                     __FUNCTION__, mCameraId, strerror(-res), res);
diff --git a/services/camera/libcameraservice/Camera2Client.h b/services/camera/libcameraservice/Camera2Client.h
index df5dbf4..1eb024a 100644
--- a/services/camera/libcameraservice/Camera2Client.h
+++ b/services/camera/libcameraservice/Camera2Client.h
@@ -99,6 +99,7 @@
 
     int getCameraId() const;
     const sp<Camera2Device>& getCameraDevice();
+    const sp<CameraService>& getCameraService();
     camera2::SharedParameters& getParameters();
 
     int getPreviewStreamId() const;
@@ -176,7 +177,7 @@
     /** Camera device-related private members */
 
     void     setPreviewCallbackFlagL(Parameters &params, int flag);
-    status_t updateRequests(const Parameters &params);
+    status_t updateRequests(Parameters &params);
 
     // Used with stream IDs
     static const int NO_STREAM = -1;
diff --git a/services/camera/libcameraservice/camera2/CallbackProcessor.cpp b/services/camera/libcameraservice/camera2/CallbackProcessor.cpp
index bccb18e..ca917f2 100644
--- a/services/camera/libcameraservice/camera2/CallbackProcessor.cpp
+++ b/services/camera/libcameraservice/camera2/CallbackProcessor.cpp
@@ -39,6 +39,7 @@
 
 CallbackProcessor::~CallbackProcessor() {
     ALOGV("%s: Exit", __FUNCTION__);
+    deleteStream();
 }
 
 void CallbackProcessor::onFrameAvailable() {
@@ -126,6 +127,11 @@
         sp<Camera2Device> device = client->getCameraDevice();
 
         device->deleteStream(mCallbackStreamId);
+
+        mCallbackHeap.clear();
+        mCallbackWindow.clear();
+        mCallbackConsumer.clear();
+
         mCallbackStreamId = NO_STREAM;
     }
     return OK;
diff --git a/services/camera/libcameraservice/camera2/CaptureSequencer.cpp b/services/camera/libcameraservice/camera2/CaptureSequencer.cpp
index 532d2aa..1c42cbf 100644
--- a/services/camera/libcameraservice/camera2/CaptureSequencer.cpp
+++ b/services/camera/libcameraservice/camera2/CaptureSequencer.cpp
@@ -388,6 +388,10 @@
         return DONE;
     }
 
+    if (l.mParameters.playShutterSound) {
+        client->getCameraService()->playSound(CameraService::SOUND_SHUTTER);
+    }
+
     mTimeoutCount = kMaxTimeoutsForCaptureEnd;
     return STANDARD_CAPTURE_WAIT;
 }
diff --git a/services/camera/libcameraservice/camera2/JpegProcessor.cpp b/services/camera/libcameraservice/camera2/JpegProcessor.cpp
index 92148ca..b230d2d 100644
--- a/services/camera/libcameraservice/camera2/JpegProcessor.cpp
+++ b/services/camera/libcameraservice/camera2/JpegProcessor.cpp
@@ -42,6 +42,7 @@
 
 JpegProcessor::~JpegProcessor() {
     ALOGV("%s: Exit", __FUNCTION__);
+    deleteStream();
 }
 
 void JpegProcessor::onFrameAvailable() {
@@ -142,6 +143,11 @@
         sp<Camera2Device> device = client->getCameraDevice();
 
         device->deleteStream(mCaptureStreamId);
+
+        mCaptureHeap.clear();
+        mCaptureWindow.clear();
+        mCaptureConsumer.clear();
+
         mCaptureStreamId = NO_STREAM;
     }
     return OK;
diff --git a/services/camera/libcameraservice/camera2/Parameters.h b/services/camera/libcameraservice/camera2/Parameters.h
index e71d086..509cc85 100644
--- a/services/camera/libcameraservice/camera2/Parameters.h
+++ b/services/camera/libcameraservice/camera2/Parameters.h
@@ -141,7 +141,7 @@
     } state;
 
     // Number of zoom steps to simulate
-    static const unsigned int NUM_ZOOM_STEPS = 10;
+    static const unsigned int NUM_ZOOM_STEPS = 30;
 
     // Full static camera info, object owned by someone else, such as
     // Camera2Device.
diff --git a/services/camera/libcameraservice/camera2/ZslProcessor.cpp b/services/camera/libcameraservice/camera2/ZslProcessor.cpp
index a39585e..ac02afc 100644
--- a/services/camera/libcameraservice/camera2/ZslProcessor.cpp
+++ b/services/camera/libcameraservice/camera2/ZslProcessor.cpp
@@ -58,6 +58,7 @@
 
 ZslProcessor::~ZslProcessor() {
     ALOGV("%s: Exit", __FUNCTION__);
+    deleteStream();
 }
 
 void ZslProcessor::onFrameAvailable() {
@@ -191,6 +192,10 @@
         device->deleteStream(mZslReprocessStreamId);
         mZslReprocessStreamId = NO_STREAM;
         device->deleteStream(mZslStreamId);
+
+        mZslWindow.clear();
+        mZslConsumer.clear();
+
         mZslStreamId = NO_STREAM;
     }
     return OK;