<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          MTK Camera 冷啟動(dòng)、前后攝切換性能優(yōu)化分析

          共 8710字,需瀏覽 18分鐘

           ·

          2024-07-10 07:45

          和你一起終身學(xué)習(xí),這里是程序員Android

          經(jīng)典好文推薦,通過閱讀本文,您將收獲以下知識(shí)點(diǎn):

          一、背景
          二、問題分解
          三、工具分析
          四、 traceView教程
          五、surface create優(yōu)化
          六、systrace的教程
          七、優(yōu)化方案
          八、前后切換速度優(yōu)化
          九、優(yōu)化方案
          十、熱啟動(dòng)優(yōu)化
          十一、解決方案:
          十二、驅(qū)動(dòng)優(yōu)化

          一、背景

          id5a、id6平臺(tái)我們的相機(jī),對(duì)比相同平臺(tái)紅米6a和6的相機(jī),冷熱啟動(dòng),前后攝切換性能要差,對(duì)比競品,我們期望優(yōu)化的比紅米6a和6的相機(jī)快10%.

          二、問題分解

          性能優(yōu)化的核心就是找到影響性能的hotspot,查找hotspot也是有套路的,首先要把相機(jī)啟動(dòng)流程分解出來,一個(gè)階段一個(gè)階段分析。

          相機(jī)的冷啟動(dòng),可以分解如下幾步:

          1.AMS啟動(dòng)相機(jī)的Activity -> 相機(jī)的Activity收到onCreated消息 (可體現(xiàn)系統(tǒng)的性能)。
          2.onCreate begin -> onCreate end(主要是ui的加載)
          3.openCamera -> CameraOpened
          4.TextureView add -> SurfaceTexture created (Surface的創(chuàng)建時(shí)間)
          5.startPreview -> PreviewStarted
          6.setWindow -> PreviewCallback

          Log如下:

          01-01 12:01:57.099   794  3012 I ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.mediatek.camera/.CameraLauncher bnds=[150,976][290,1202] (has extras)} from uid 10064
          01-01 12:01:57.169 8261 8261 D CamAp_QuickActivity: [ 0.000ms][BEGIN] onCreate
          01-01 12:01:57.196 8261 8295 I CamAp_API1-Handler-0: [openCamera]+
          01-01 12:01:57.217 532 2586 I mtkcam-dev1: [createSpecificCameraDevice1] dlopen libmtkcam_device1.so +
          01-01 12:01:57.224 532 2586 I mtkcam-dev1: [createSpecificCameraDevice1] dlopen libmtkcam_device1.so -
          01-01 12:01:57.259 532 2586 I mtkcam-dev1: [createSpecificCameraDevice1] - 0xe6a0ec00
          01-01 12:01:57.260 532 2586 I mtkcam-dev1: 0[CameraDevice1Base::open] +
          01-01 12:01:57.419 532 2586 I mtkcam-dev1: 0[CameraDevice1Base::open] Add new cameraId 0 - 0xe6a0ec00
          01-01 12:01:57.419 532 2586 I mtkcam-dev1: 0[CameraDevice1Base::open] -

          01-01 12:01:57.424 8261 8295 I CamAp_API1-Handler-0: [openCamera]-, executing time = 228ms.
          01-01 12:01:57.537 8261 8261 D CamAp_QuickActivity: [367.294ms] [END] onCreate
          01-01 12:01:57.542 8261 8261 D CamAp_QuickActivity: [ 0.000ms][BEGIN] onStart
          01-01 12:01:57.546 8261 8261 D CamAp_QuickActivity: [ 3.762ms] [END] onStart
          01-01 12:01:57.549 8261 8261 D CamAp_QuickActivity: [ 0.000ms][BEGIN] onResume
          01-01 12:01:57.552 8261 8261 D CamAp_QuickActivity: isKeyguardLocked = false
          01-01 12:01:57.552 8261 8261 D CamAp_QuickActivity: onResume --> onPermissionResumeTasks()
          01-01 12:01:57.600 8261 8261 D CamAp_QuickActivity: [ 50.774ms] [END] onResume

          01-01 12:01:57.685 8261 8294 I CamAp_API1-Handler-0: [setPreviewDisplay]+, pending time = 0ms.
          01-01 12:01:57.686 8261 8294 I CamAp_API1-Handler-0: [setPreviewDisplay]-, executing time = 1ms.

          01-01 12:01:57.700 8261 8294 I CamAp_API1-Handler-0: [startPreview]+, pending time = 0ms.
          01-01 12:01:57.701 532 2586 W mtkcam-dev1: 0[CameraDevice1Base::initDisplayClient] NULL window is passed into...
          01-01 12:01:57.701 532 2586 I mtkcam-dev1: 0[CameraDevice1Base::startPreview] +

          01-01 12:01:57.720 8261 8261 I CamAp_TextureViewController: updatePreviewSize: new size (960 , 720 ) current size (0 , 0 ),mIsSurfaceCreated = false listener = com.mediatek.camera.common.mode.photo.PhotoMode$SurfaceChangeListener@a79ec89

          01-01 12:01:57.735 532 2586 I mtkcam-dev1: 0[CameraDevice1Base::startPreview] - status(0)

          01-01 12:01:57.736 8261 8294 I CamAp_API1-Handler-0: [startPreview]-, executing time = 36ms.
          01-01 12:01:57.948 532 8363 I MtkCam/DCNode: [0::waitPreviewReady]wait for start preview done +
          01-01 12:01:58.087 532 8363 I MtkCam/DCNode: [0::waitPreviewReady]wait for start preview done - , use 130 ms

          01-01 12:01:58.053 8261 8261 D CamAp_TextureViewController: onSurfaceTextureAvailable surface = android.graphics.SurfaceTexture@2d48d1c width 720 height 960

          01-01 12:01:58.056 8261 8294 I CamAp_API1-Handler-0: [setPreviewTexture]+, pending time = 0ms.
          01-01 12:01:58.087 532 8363 I MtkCam/CamAdapter: (8363)[transitState] StateIdle --> StatePreview
          01-01 12:01:58.089 532 2586 I MtkCam/DisplayClient: [setWindow] + window(0xe6a0ecf0), WxH=960x720, count(6), iNativeWindowConsumerUsage(256)

          01-01 12:01:58.093 8261 8294 I CamAp_API1-Handler-0: [setPreviewTexture]-, executing time = 37ms.

          01-01 12:01:58.279 8261 8295 D CamAp_PhotoDeviceController: [onPreviewFrame] mModeDeviceCallback = com.mediatek.camera.common.mode.photo.PhotoMode@feb2273

          其中OnCreate begin -> onCreate end:花了367ms

          01-01 12:01:57.169  8261  8261 D CamAp_QuickActivity: [  0.000ms][BEGIN] onCreate
          01-01 12:01:57.537 8261 8261 D CamAp_QuickActivity: [367.294ms] [END] onCreate

          其中openCamera: 花了238ms


          01-01 12:01:57.196 8261 8295 I CamAp_API1-Handler-0: [openCamera]+
          01-01 12:01:57.424 8261 8295 I CamAp_API1-Handler-0: [openCamera]-, executing time = 228ms.

          其中Surface Create: 花了333ms

          01-01 12:01:57.720  8261  8261 I CamAp_TextureViewController: updatePreviewSize: new size (960 , 720 ) current size (0 , 0 ),mIsSurfaceCreated = false listener = com.mediatek.camera.common.mode.photo.PhotoMode$SurfaceChangeListener@a79ec89
          01-01 12:01:58.053 8261 8261 D CamAp_TextureViewController: onSurfaceTextureAvailable surface = android.graphics.SurfaceTexture@2d48d1c width 720 height 960

          其中startPreview:花386ms

          01-01 12:01:57.701   532  2586 I mtkcam-dev1: 0[CameraDevice1Base::startPreview] +
          01-01 12:01:58.087 532 8363 I MtkCam/CamAdapter: (8363)[transitState] StateIdle --> StatePreview

          其中startWindow -> PreveiwCallback:花87ms

          01-01 12:01:58.093  8261  8294 I CamAp_API1-Handler-0: [setPreviewTexture]-, executing time = 37ms.

          01-01 12:01:58.279 8261 8295 D CamAp_PhotoDeviceController: [onPreviewFrame] mModeDeviceCallback = com.mediatek.camera.common.mode.photo.PhotoMode@feb2273

          其中花時(shí)間的步驟,是2、3、4、5,主要ui加載,openCamera,surfaceCreated、startPreview。openCamera和startPreview花時(shí)間需要驅(qū)動(dòng)優(yōu)化。ui加載和surfaceCreate需要上層看。

          三、工具分析

          traceView分析ui加載,發(fā)現(xiàn)沒有可優(yōu)化的,現(xiàn)在加載的ui都是需要一進(jìn)去就要看見的,不需要進(jìn)去看見的view,都使用viewStub延時(shí)加載處理了,并且關(guān)于ui也優(yōu)化了好幾波。優(yōu)化空間比較小。不過針對(duì)冷啟動(dòng),可以使用內(nèi)存常駐的方案,這樣實(shí)際上冷啟動(dòng)就是熱啟動(dòng)。主要原因是相機(jī)在手機(jī)啟動(dòng)時(shí),收到啟動(dòng)廣播會(huì)啟動(dòng)一個(gè)服務(wù),用于檢測是否溫度過高,服務(wù)拉起了相機(jī)應(yīng)用。內(nèi)存常駐后,此應(yīng)用就不被殺掉了。這樣啟動(dòng)速度優(yōu)化很大。
          目前的方案:2G以上項(xiàng)目默認(rèn)使用內(nèi)存常駐方案。

          四、 traceView教程

          https://www.jianshu.com/p/f81b20b9a7e2
          https://developer.android.com/studio/profile/traceview

          五、surface create優(yōu)化

          現(xiàn)在主要的大頭就是Surface create優(yōu)化了。systrace分析創(chuàng)建surface過程,發(fā)現(xiàn)ArcFilter HandleThread一直在wait。

          六、systrace的教程

          https://developer.android.google.cn/studio/command-line/systrace

          查看代碼,是濾鏡等待arc算法引擎初始化和GL引擎初始化。這里的設(shè)計(jì)是有爭議的,其實(shí)相機(jī)啟動(dòng)的時(shí)候并沒有開啟濾鏡,但是要初始化濾鏡的引擎。做耗時(shí)benchmark:

          01-02 01:22:07.991 23458-23554/? I/CamAp_TextureEnvExt: handleGlEnvInit(): Enter
          01-02 01:22:07.991 23458-23458/? V/CamAp_TextureEnvExt: getCamSurfaceTexture:: in -1
          01-02 01:22:08.090 23458-23554/? I/CamAp_TextureEnvExt: handleGlEnvInit(): Exit with bRet = EGL_SUCCESS
          01-02 01:22:08.091 23458-23554/? I/CamAp_TextureEnvExt: handleArcFilterEngine(): init begin
          01-02 01:22:08.095 23458-23458/? V/CamAp_TextureEnvExt: getCamSurfaceTexture:: ID=1
          01-02 01:22:08.211 23458-23554/? I/CamAp_TextureEnvExt: handleArcFilterEngine(): init end engine = 0,prepareEngine=0

          可以看出:初始化GLEnv需要99ms,初始引擎需要120ms.

          七、優(yōu)化方案

          這有兩種優(yōu)化方案:

          1. 啟動(dòng)時(shí),不加載濾鏡引擎,切換到濾鏡時(shí)加載。后果是切換濾鏡時(shí)會(huì)卡一下,需要修改整個(gè)流程,代碼修改量大。

          2. 分步初始化GLEnv和濾鏡引擎,理論上可以優(yōu)化120ms+,創(chuàng)建Surface和startPreview并行執(zhí)行。代碼改動(dòng)小,并且能達(dá)到優(yōu)化效果。

          目前使用第二種方案,代碼提交記錄:

          http://192.168.10.10/#/c/213235/

          八、前后切換速度優(yōu)化

          前后切換速度對(duì)上層來說,主要有兩個(gè)方面影響,一是翻轉(zhuǎn)動(dòng)畫,一是高斯模糊。翻轉(zhuǎn)動(dòng)畫使用高速相機(jī)測量,只有9幀,平臺(tái)性能限制,有一種帶不動(dòng)的感覺,對(duì)標(biāo)機(jī)也沒有,和產(chǎn)品溝通去掉。能優(yōu)化的就是高斯模糊了。

          高斯模糊的耗時(shí)benchmark:

          01-02 02:00:21.636 8089-8089/? I/CamAp_GaussianBlur: GaussianBlur,create render:42
          01-02 02:00:21.636 8089-8089/? D/CamAp_GaussianBlur: preview width 750 height 1500
          01-02 02:00:21.731 8089-8089/? I/CamAp_GaussianBlur: getPreview bitmap spent time: 125
          01-02 02:00:21.821 8089-8089/? I/CamAp_GaussianBlur: blurBitmap,render bitmap:112

          整個(gè)高斯模糊流程大概需要花279ms,主要耗時(shí)是getPreview和blurBitmap,還有init每次都要做。

          九、優(yōu)化方案

          init需要花40多少ms,只做一次。getPreview,對(duì)于高斯模糊,我們不需要一張清晰的圖片,反正后面也要做模糊。getPreview時(shí),我們?cè)O(shè)置一個(gè)采樣率,采樣質(zhì)量降低16倍,做高斯模糊時(shí),我們?cè)O(shè)置一個(gè)較小模糊半徑因子,目前為5,這樣做模糊的速度快,模糊效果好。

          優(yōu)化后的耗時(shí)benchmark:

          01-02 02:14:15.628 20947-20947/? D/CamAp_GaussianBlur: preview width 750 height 1500
          01-02 02:14:15.632 20947-20947/? I/CamAp_GaussianBlur: getPreview bitmap spent time: 4
          01-02 02:14:15.636 20947-20947/? I/CamAp_GaussianBlur: blurBitmap,render bitmap:4

          代碼提交記錄:

          http://192.168.10.10/#/c/213235/

          十、熱啟動(dòng)優(yōu)化

          熱啟動(dòng)優(yōu)化,和對(duì)比機(jī)不同的是,在預(yù)覽沒有出來之前,我們做了一個(gè)高斯模糊的蓋板。和產(chǎn)品溝通需要去掉,去掉蓋板比較容易。引發(fā)兩個(gè)問題需要解決。

          1. TextureView沒有被銷毀,會(huì)保留上一幀。主要表現(xiàn)熱啟動(dòng)會(huì)閃上一幀。

          2. framework會(huì)有一個(gè)screenshot界面,同樣會(huì)閃上幀。

          十一、解決方案:

          1. 在pause時(shí),把TextureView的alpha設(shè)置為0,第一幀上來,再把a(bǔ)lpha設(shè)置1,讓其顯示。

          2. 應(yīng)用層關(guān)掉screenshot.

          十二、驅(qū)動(dòng)優(yōu)化

          關(guān)于openCamera和startPreview優(yōu)化,底層優(yōu)化了3a算法、加入了fastae和使用speed mode模式。詳情可以咨詢彭葉斌同學(xué)。

          原文鏈接:https://www.jianshu.com/p/77d035588bd4

          相關(guān)文章友情推薦 

          1. Android開發(fā)干貨分享

          至此,本篇已結(jié)束。轉(zhuǎn)載網(wǎng)絡(luò)的文章,小編覺得很優(yōu)秀,如有侵權(quán),懇請(qǐng)聯(lián)系小編刪除,歡迎您的建議與指正。同時(shí)期待您的關(guān)注,感謝您的閱讀,謝謝!

          點(diǎn)個(gè)在看,方便您使用時(shí)快速查看!

          瀏覽 118
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人免费在线视频 | 91成人无码视频 | 免费人成视频网站 | 毛片看看| 青草视频在线观看视频 |