[MTK] 第三方应用打开Camera, preview方向不对

文摘 MediaTek 2022-01-12 阅读:11075

问题描述:

打开第三方应用,preview方向不符合预期。

问题排查:

1.安装ctsVerifier.apk,测试里面的Camera->Camera Formats,check出问题的那颗摄像头preview的方向是否是正确的。

1)若不正确,说明sensor orientation配置错误,请修改sensor orientation确保cts方向正常
 vendor/mediatek/proprietary/custom/{项目}/hal/imgsensor_src/cfg_setting_imgsensor.cpp
    {
        .sensorIdx     = IMGSENSOR_SENSOR_IDX_MAIN,
        .mclk          = eMclk_1,
        .port          = EMipiPort_CSI1,
        .dir           = CUSTOM_CFG_DIR_REAR,
        .bitOrder      = CUSTOM_CFG_BITORDER_9_2,
        .orientation   = 270,//修改这里
        .horizontalFov = 67,
        .verticalFov   = 49,
        .PadPclkInv    = 0,
    },

修改是否生效可以通过dump metadata确认:adb shell dumpsys media.camera -v 2 > metadata.txt

在metadata.txt里搜索"Facing|Orientation"关键字。

2)若正确,go to 2.

2. 确认第三方应用preview是走api几,关键log:CameraService: CameraService::connect call (PID -1 "com.tencent.mobileqq", camera ID 1) for HAL version default and Camera API version 1

1)如果preview走的是api1

App Call setDisplayOrientation(int) to ensure correct orientation of preview. 最终set preview方向到nativewindow的地方在这里:

frameworks/av/services/camera/libcameraservice/api1/Camera2Client.cpp

 1644  status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
 1645      int transform = Parameters::degToTransform(degrees,
 1646              mCameraFacing == CAMERA_FACING_FRONT);
 1647      if (transform == -1) {
 1648          ALOGE("%s: Camera %d: Error setting %d as display orientation value",
 1649                  __FUNCTION__, mCameraId, degrees);
 1650          return BAD_VALUE;
 1651      }
 1652      SharedParameters::Lock l(mParameters);
 1653      if (transform != l.mParameters.previewTransform &&
 1654              getPreviewStreamId() != NO_STREAM) {
 1655          mDevice->setStreamTransform(getPreviewStreamId(), transform);
 1656      }
 1657      l.mParameters.previewTransform = transform;
 1658      return OK;
 1659  }

可以在[commandSetDisplayOrientationL]这里加log确认第三方应用传来的[degrees]和mirror是多少。

1.1)如果是同一个app都有问题,可以在这里加包名强制调整degrees。patch用下:
 diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index b043c0b557..22de4db7b2 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -63,7 +63,8 @@ Camera2Client::Camera2Client(const sp& cameraService,
 mParameters(api1CameraId, cameraFacing)
 {
 ATRACE_CALL();
+ mclientPackageName = clientPackageName;
+ALOGE("mclientPackageName=%s",String8(mclientPackageName).string());
 SharedParameters::Lock l(mParameters);
 l.mParameters.state = Parameters::DISCONNECTED;
 }
@@ -1655,8 +1656,17 @@ status_t Camera2Client::commandStopSmoothZoomL() {
 ALOGE("%s: Unimplemented!", __FUNCTION__);
 return OK;
 }
+#include <cutils/properties.h>

 status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
+ #if 1
+ int32_t currentDumpProp = property_get_int32("camera.debug.api1.preview.degrees",0);
+ if(!strcmp((String8)mclientPackageName.string(),"com.fjg.android.scan")){ //修改包名
+ ALOGE("adjust app degrees %d to currentDumpProp=%d",degrees,currentDumpProp);
+ degrees = currentDumpProp;
+
+ }
+ #endif
 int transform = Parameters::degToTransform(degrees,
 mCameraFacing == CAMERA_FACING_FRONT);
 if (transform == -1) {
@@ -1670,6 +1680,8 @@ status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
 mDevice->setStreamTransform(getPreviewStreamId(), transform);
 }
 l.mParameters.previewTransform = transform;
+ ALOGE(" %s: Camera %d: setting %d as display orientation value,facing:%d",
+ __FUNCTION__, mCameraId, degrees,mCameraFacing);
 return OK;
 }

diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h
index 03ca44a421..56f11a09a8 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.h
+++ b/services/camera/libcameraservice/api1/Camera2Client.h
@@ -240,6 +240,7 @@ private:
 int32_t mLatestFailedRequestId = -1;
 status_t waitUntilRequestIdApplied(int32_t requestId, nsecs_t timeout);
 status_t waitUntilCurrentRequestIdLocked();
+ String16 mclientPackageName;
 };

 }; // namespace android

修改思路是:在framework层根据app package name调整preview orientation。

测试方法:

adb root
adb remount
adb shell setenforce 0
adb shell setprop camera.debug.api1.preview.degrees 180 //取0、90、180、270中一个。

打开camera测试
1.2)如果同一个app的不同activity方向不同,可以通过activity名字区分,修改在java层是因为这里面可以区分是哪个activity,patch如下:
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 87192d885085..d43aaa5c3daf 100755
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -7705,6 +7705,15 @@ public final class ActivityThread extends ClientTransactionHandler {
 throw new RuntimeException("Main thread loop unexpectedly exited");
 }

+ public String currentActivityName() {
+ String classname =null;
+ ActivityManager manager = (ActivityManager) getSystemContext().getSystemService(Context.ACTIVITY_SERVICE);
+ ActivityManager.RunningTaskInfo info = manager.getRunningTasks(1).get(0);
+ classname = info.topActivity.getClassName();
+ Log.e("ActivityThread","currentActivityName classname="+classname);
+ return classname;
+ }
+
 /**
 * Call various initializer APIs in mainline modules that need to be called when each process
 * starts.

diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 25279b31b5d1..56360697dd2d 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java

@@ -55,6 +55,7 @@ import android.util.Log;
 import android.view.Surface;
 import android.view.SurfaceHolder;

+
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.IAppOpsCallback;
 import com.android.internal.app.IAppOpsService;
@@ -306,6 +307,25 @@ public class Camera {
 } catch (RemoteException e) {
 Log.e(TAG, "Audio service is unavailable for queries");
 }
+
+ String packageName = ActivityThread.currentOpPackageName();
+ String activityName = ActivityThread.currentActivityThread().currentActivityName();
+ Log.i("Camerajava", "Original cameraInfo.orientation = " + cameraInfo.orientation+",cameraInfo.facing="+cameraInfo.facing);
+ Log.i("Camerajava", "getCameraInfo currentOpPackageName = " + packageName);
+ Log.i("Camerajava", "getCameraInfo activitiName = " + activityName);
+ if(! packageName.equals("com.mediatek.camera")) {
+ if(packageName.equals("com.tencent.mobileqq")) { //修改包名
+ if(activityName.equals("com.tencent.av.ui.AVActivity")) { //修改activity名字
+ if (cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT){
+ Log.i("Camerajava", "getCameraInfo bef cameraInfo.orientation = " + cameraInfo.orientation);
+ int ori = android.os.SystemProperties.getInt("vendor.camerajava.ori", 270);
+ Log.i("Camerajava", "getCameraInfo ori = " + ori);
+ cameraInfo.orientation = ori;
+ }
+ }
+ }
+ }
+
 }
 private native static void _getCameraInfo(int cameraId, CameraInfo cameraInfo);

修改思路是:对于特定的activity,通过set property调整app get到的sensor角度,从而间接影响app set下来的preview的orientation。

测试方法:

adb root
adb remount
adb shell setenforce 0
adb shell setprop vendor.camerajava.ori 180 //取0、90、180、270中一个。
打开camera测试
2)preview走的是api2

app无需set preview方向,是framework层自行根据sensor orientation、facing计算nativewindow的transform值。

 /frameworks/av/camera/CameraUtils.cpp

  status_t CameraUtils::getRotationTransform(const CameraMetadata& staticInfo,
   /*out*/int32_t* transform) {
 ... int orientation = entry.data.i32[0];

0条评论

© 2024 芯缘异码. Powered by Typecho