OSDN Git Service

Camera2: create new streams if surface size has changed
authorMikael Persson <mikael.persson@intel.com>
Thu, 26 Nov 2015 11:34:29 +0000 (12:34 +0100)
committerChih-Wei Huang <cwhuang@linux.org.tw>
Wed, 20 Jul 2016 09:53:21 +0000 (17:53 +0800)
When a new capture session is created, the old streams
are re-used if same surface and rotation. However, if the
surface has changed size, we must re-create the stream
to ensure HAL is configured properly, which includes
setting up proper sensor resolution.

This is an issue in e.g. CTS testNoiseReductionModes
and testEdgeModeControl, where a new preview with different
size can be setup without first stopping the previous one.
The same preview surface is used here, but with changed size.

Change-Id: I3b88a95209e83cf1cef0f4d1f791c87b0feb093f
Tracked-On: https://jira01.devtools.intel.com/browse/OAM-10333
Signed-off-by: Mikael Persson <mikael.persson@intel.com>
Reviewed-on: https://android.intel.com:443/441205

core/java/android/hardware/camera2/impl/CameraDeviceImpl.java

index 6e02df1..8bfcc70 100644 (file)
@@ -95,6 +95,8 @@ public class CameraDeviceImpl extends CameraDevice {
             new SimpleEntry<>(REQUEST_ID_NONE, null);
     private final SparseArray<OutputConfiguration> mConfiguredOutputs =
             new SparseArray<>();
+    private final SparseArray<Size> mConfiguredOutputSizes =
+            new SparseArray<>();
 
     private final String mCameraId;
     private final CameraCharacteristics mCharacteristics;
@@ -388,7 +390,14 @@ public class CameraDeviceImpl extends CameraDevice {
                 if (!outputs.contains(outConfig)) {
                     deleteList.add(streamId);
                 } else {
-                    addSet.remove(outConfig);  // Don't create a stream previously created
+                    // Even if same surface and rotation, the surface can have re-sized.
+                    // If so, we must create a new stream to ensure HAL is configured correctly.
+                    Size outSize = SurfaceUtils.getSurfaceSize(outConfig.getSurface());
+                    if (!outSize.equals(mConfiguredOutputSizes.valueAt(i))) {
+                        deleteList.add(streamId);
+                    } else {
+                        addSet.remove(outConfig);  // Don't create a stream previously created
+                    }
                 }
             }
 
@@ -421,13 +430,16 @@ public class CameraDeviceImpl extends CameraDevice {
                 for (Integer streamId : deleteList) {
                     mRemoteDevice.deleteStream(streamId);
                     mConfiguredOutputs.delete(streamId);
+                    mConfiguredOutputSizes.delete(streamId);
                 }
 
                 // Add all new streams
                 for (OutputConfiguration outConfig : outputs) {
                     if (addSet.contains(outConfig)) {
                         int streamId = mRemoteDevice.createStream(outConfig);
+                        Size outSize = SurfaceUtils.getSurfaceSize(outConfig.getSurface());
                         mConfiguredOutputs.put(streamId, outConfig);
+                        mConfiguredOutputSizes.put(streamId, outSize);
                     }
                 }