日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

android6.0源码分析之Camera API2.0下的Preview(预览)流程分析

發布時間:2025/3/15 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android6.0源码分析之Camera API2.0下的Preview(预览)流程分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、Camera2 preview的應用層流程分析

preview流程都是從startPreview開始的,所以來看startPreview方法的代碼:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//OneCameraImpl.java</span> <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">startPreview</span>(Surface previewSurface, CaptureReadyCallback listener) {mPreviewSurface = previewSurface;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//根據Surface以及CaptureReadyCallback回調來建立preview環境</span>setupAsync(mPreviewSurface, listener); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

這其中有一個比較重要的回調CaptureReadyCallback,先分析setupAsync方法:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//OneCameraImpl.java</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setupAsync</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> Surface previewSurface, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> CaptureReadyCallback listener) {mCameraHandler.post(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Runnable() {<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">run</span>() {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//建立preview環境</span>setup(previewSurface, listener);}}); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>

這里通過CameraHandler來post一個Runnable對象,它只會調用Runnable的run方法,它仍然屬于UI線程,并沒有創建新的線程。所以,繼續分析setup方法:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// OneCameraImpl.java</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setup</span>(Surface previewSurface, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> CaptureReadyCallback listener) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mCaptureSession != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {mCaptureSession.abortCaptures();mCaptureSession = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;}List<Surface> outputSurfaces = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ArrayList<Surface>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>);outputSurfaces.add(previewSurface);outputSurfaces.add(mCaptureImageReader.getSurface());<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//創建CaptureSession會話來與Camera Device發送Preview請求</span>mDevice.createCaptureSession(outputSurfaces, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> CameraCaptureSession.StateCallback() {<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onConfigureFailed</span>(CameraCaptureSession session) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//如果配置失敗,則回調CaptureReadyCallback的onSetupFailed方法</span>listener.onSetupFailed();}<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onConfigured</span>(CameraCaptureSession session) {mCaptureSession = session;mAFRegions = ZERO_WEIGHT_3A_REGION;mAERegions = ZERO_WEIGHT_3A_REGION;mZoomValue = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>f;mCropRegion = cropRegionForZoom(mZoomValue);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//調用repeatingPreview來啟動preview</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> success = repeatingPreview(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (success) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//若啟動成功,則回調CaptureReadyCallback的onReadyForCapture,表示準備拍照成功</span>listener.onReadyForCapture();} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//若啟動失敗,則回調CaptureReadyCallback的onSetupFailed,表示preview建立失敗</span>listener.onSetupFailed();}}<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onClosed</span>(CameraCaptureSession session) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onClosed(session);}}, mCameraHandler);} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (CameraAccessException ex) {Log.e(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Could not set up capture session"</span>, ex);listener.onSetupFailed();} }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li></ul>

首先,調用Device的createCaptureSession方法來創建一個會話,并定義了會話的狀態回調CameraCaptureSession.StateCallback(),其中,當會話創建成功,則會回調onConfigured()方法,在其中,首先調用repeatingPreview來啟動preview,然后處理preview的結果并調用先前定義的CaptureReadyCallback來通知用戶進行Capture操作。先分析repeatingPreview方法:

<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// OneCameraImpl.java</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> boolean repeatingPreview(Object <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">tag</span>) {try {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//通過CameraDevice對象創建一個CaptureRequest的preview請求</span>CaptureRequest<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>Builder builder <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> mDevice<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>createCaptureRequest(CameraDevice<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>TEMPLATE_PREVIEW);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//添加預覽的目標Surface</span>builder<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>addTarget(mPreviewSurface);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//設置預覽模式</span>builder<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">set</span>(CaptureRequest<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>CONTROL_MODE, CameraMetadata<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>CONTROL_MODE_AUTO);addBaselineCaptureKeysToRequest(builder);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//利用會話發送請求,mCaptureCallback為</span>mCaptureSession<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>setRepeatingRequest(builder<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>build(), mCaptureCallback,mCameraHandler);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Log</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>v(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">TAG</span>, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>format(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Sent repeating Preview request, zoom = %.2f"</span>, mZoomValue));<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>;} catch (CameraAccessException ex) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Log</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>e(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">TAG</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Could not access camera setting up preview."</span>, ex);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">false</span>;} }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li></ul>

首先調用CameraDeviceImpl的createCaptureRequest方法創建類型為TEMPLATE_PREVIEW 的CaptureRequest,然后調用CameraCaptureSessionImpl的setRepeatingRequest方法將此請求發送出去:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//CameraCaptureSessionImpl.java</span> <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">synchronized</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">setRepeatingRequest</span>(CaptureRequest request, CaptureCallback callback,Handler handler) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> CameraAccessException {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (request == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> IllegalArgumentException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"request must not be null"</span>);} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (request.isReprocess()) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> IllegalArgumentException(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"repeating reprocess requests are not supported"</span>);}checkNotClosed();handler = checkHandler(handler, callback);...<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//將此請求添加到待處理的序列里</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> addPendingSequence(mDeviceImpl.setRepeatingRequest(request,createCaptureCallbackProxy(handler, callback), mDeviceHandler)); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li></ul>

至此應用層的preview的請求流程分析結束,繼續分析其結果處理,如果preview開啟成功,則會回調CaptureReadyCallback的onReadyForCapture方法,現在分析CaptureReadyCallback回調:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//CaptureModule.java</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> CaptureReadyCallback() {<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onSetupFailed</span>() {mCameraOpenCloseLock.release();Log.e(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Could not set up preview."</span>);mMainThread.execute(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Runnable() {<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">run</span>() {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mCamera == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {Log.d(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Camera closed, aborting."</span>);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;}mCamera.close();mCamera = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;}});}<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onReadyForCapture</span>() {mCameraOpenCloseLock.release();mMainThread.execute(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Runnable() {<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">run</span>() {Log.d(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Ready for capture."</span>);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mCamera == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {Log.d(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Camera closed, aborting."</span>);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;}<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//</span>onPreviewStarted();onReadyStateChanged(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>);mCamera.setReadyStateChangedListener(CaptureModule.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>);mUI.initializeZoom(mCamera.getMaxZoom());mCamera.setFocusStateListener(CaptureModule.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>);}});} }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li></ul>

根據前面的分析,預覽成功后會回調onReadyForCapture方法,它主要是通知主線程的狀態改變,并設置Camera的ReadyStateChangedListener的監聽,其回調方法如下:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//CaptureModule.java</span> <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onReadyStateChanged</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> readyForCapture) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (readyForCapture) {mAppController.getCameraAppUI().enableModeOptions();}mAppController.setShutterEnabled(readyForCapture); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>

如代碼所示,當其狀態變成準備好拍照,則將會調用CameraActivity的setShutterEnabled方法,即使能快門按鍵,此時也就是說預覽成功結束,可以按快門進行拍照了,所以,到這里,應用層的preview的流程基本分析完畢,下圖是應用層的關鍵調用的流程時序圖:?


2、Camera2 preview的Native層流程分析

分析Preview的Native的代碼真是費了九牛二虎之力,若有分析不正確之處,請各位大神指正,在第一小節的后段最后會調用CameraDeviceImpl的setRepeatingRequest方法來提交請求,而在android6.0源碼分析之Camera API2.0簡介中,分析了Camera2框架Java IPC通信使用了CameraDeviceUser來進行通信,所以看Native層的ICameraDeviceUser的onTransact方法來處理請求的提交:

<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//ICameraDeviceUser.cpp</span> status_t BnCameraDeviceUser<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::onTransact</span>(uint32_t code, const Parcel<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">data</span>, Parcel<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span> reply, uint32_t flags){switch(code) {…<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//請求提交</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">case</span> SUBMIT_REQUEST: {CHECK_INTERFACE(ICameraDeviceUser, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">data</span>, reply);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// arg0 = request</span>sp<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>CaptureRequest<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span> request;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">data</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>readInt32() <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {request <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">new</span> CaptureRequest();request<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>readFromParcel(const_cast<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>Parcel<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*></span>(<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">data</span>));}<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// arg1 = streaming (bool)</span>bool <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">repeating</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">data</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>readInt32();<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// return code: requestId (int32)</span>reply<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>writeNoException();int64_t lastFrameNumber <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-</span><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//將實現BnCameraDeviceUser的對下崗的submitRequest方法代碼寫入Binder</span>reply<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>writeInt32(submitRequest(request, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">repeating</span>, <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span>lastFrameNumber));reply<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>writeInt32(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);reply<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>writeInt64(lastFrameNumber);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> NO_ERROR;} break;<span class="hljs-attribute" style="box-sizing: border-box;">...</span> }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li></ul>

CameraDeviceClientBase繼承了BnCameraDeviceUser類,所以CameraDeviceClientBase相當于IPC Binder中的client,所以會調用其submitRequest方法,此處,至于IPC Binder通信原理不做分析,其參照其它資料:

<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//CameraDeviceClient.cpp</span> status_t CameraDeviceClient<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::submitRequest</span>(sp<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>CaptureRequest<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span> request,bool streaming,<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*out*/</span>int64_t<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span> lastFrameNumber) {<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">List</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>sp<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>CaptureRequest<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span> requestList;requestList<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>push_back(request);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> submitRequestList(requestList, streaming, lastFrameNumber); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

簡單的調用,繼續分析submitRequestList:

<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">// CameraDeviceClient status_t CameraDeviceClient::submitRequestList(List<sp<CaptureRequest> > requests,bool streaming, int64_t* lastFrameNumber) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>//Metadata鏈表List<const CameraMetadata> metadataRequestList;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end(); ++it) {sp<CaptureRequest> request = *it;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>//初始化Metadata數據CameraMetadata metadata(request->mMetadata);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>//設置Stream的容量Vector<int32_t> outputStreamIds;outputStreamIds.setCapacity(request->mSurfaceList.size());//循環初始化Surface<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (size_t i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < request->mSurfaceList.size(); ++i) {sp<Surface> surface = request->mSurfaceList[i];<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (surface == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) continue;sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();int idx = mStreamMap.indexOfKey(IInterface::asBinder(gbp));<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>int streamId = mStreamMap.valueAt(idx);outputStreamIds.push_back(streamId);}//更新數據metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS, &outputStreamIds[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>],outputStreamIds.size());<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (request->mIsReprocess) {metadata.update(ANDROID_REQUEST_INPUT_STREAMS, &mInputStream.id, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);}metadata.update(ANDROID_REQUEST_ID, &requestId, /*size*/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);loopCounter++; // loopCounter starts from <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>//壓棧metadataRequestList.push_back(metadata);}mRequestIdCounter++;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (streaming) {//預覽會走此條通道res = mDevice->setStreamingRequestList(metadataRequestList, lastFrameNumber);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (res != OK) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {mStreamingRequestList.push_back(requestId);}} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {//Capture等走此條通道res = mDevice->captureList(metadataRequestList, lastFrameNumber);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (res != OK) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>}}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (res == OK) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> requestId;}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> res; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li></ul>

setStreamingRequestList和captureList方法都調用了submitRequestsHelper方法,只是他們的repeating參數一個ture,一個為false,而本節分析的preview調用的是setStreamingRequestList方法,并且API2.0下Device的實現為Camera3Device,所以看它的submitRequestsHelper實現:

<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">// Camera3Device.cpp status_t Camera3Device::submitRequestsHelper(const List<const CameraMetadata> &requests, bool repeating,/*out*/int64_t *lastFrameNumber) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>RequestList requestList;//在這里面會進行CaptureRequest的創建,并調用configureStreamLocked進行stream的配置,主要是設置了一個回調captureResultCb,即后面要分析的重要的回調res = convertMetadataListToRequestListLocked(requests, /*out*/&requestList);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (repeating) {//眼熟不,這個方法名和應用層中CameraDevice的setRepeatingRequests一樣res = mRequestThread->setRepeatingRequests(requestList, lastFrameNumber);} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {//不需重復,即repeating為false時,調用此方法來講請求提交res = mRequestThread->queueRequestList(requestList, lastFrameNumber);}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> res; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li></ul>

從代碼可知,在Camera3Device里創建了要給RequestThread線程,調用它的setRepeatingRequests或者queueRequestList方法來將應用層發送過來的Request提交,繼續看setRepeatingRequests方法:

<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Camera3Device.cpp</span> status_t Camera3Device<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::RequestThread</span><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::setRepeatingRequests</span>(const RequestList <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span>requests,<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*out*/</span>int64_t <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>lastFrameNumber) {Mutex<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::Autolock</span> l(mRequestLock);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (lastFrameNumber <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NULL</span>) {<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>lastFrameNumber <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> mRepeatingLastFrameNumber;}mRepeatingRequests<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>clear();<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//將其插入mRepeatingRequest鏈表</span>mRepeatingRequests<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>insert(mRepeatingRequests<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>begin(),requests<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>begin(), requests<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>end());unpauseForNewRequests();mRepeatingLastFrameNumber <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> NO_IN_FLIGHT_REPEATING_FRAMES;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> OK; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li></ul>

至此,Native層的preview過程基本分析結束,下面的工作將會交給Camera HAL層來處理,先給出Native層的調用時序圖:?


3、Camera2 preview的CameraHAL層流程分析

本節將不再對Camera的HAL層的初始化以及相關配置進行分析,只對preview等相關流程中的frame metadata的處理流程進行分析,具體的CameraHAL分析請參考android6.0源碼分析之Camera2 HAL分析.在第二小節的submitRequestsHelper方法中調用convertMetadataListToRequestListLocked的時候會進行CaptureRequest的創建,并調用configureStreamLocked進行stream的配置,主要是設置了一個回調captureResultCb,所以Native層在request提交后,會回調此captureResultCb方法,首先分析captureResultCb:

<code class="hljs autohotkey has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">// QCamera3HWI.cpp <span class="hljs-label" style="box-sizing: border-box;">void QCamera3HardwareInterface::</span>captureResultCb(mm_camer<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">a_super</span>_buf_t *metadat<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">a_buf</span>,camera3_stream_buffer_t *buffer, uint32_t frame_number) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (metadat<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">a_buf</span>) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mBatchSize) {//批處理模式,但代碼也是循環調用handleMetadataWithLock方法handleBatchMetadata(metadat<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">a_buf</span>, <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span> /* free_and_bufdone_met<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">a_buf</span> */)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> { /* mBatchSize = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> */pthread_mutex_lock(&mMutex)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">; </span>//處理元數據handleMetadataWithLock(metadat<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">a_buf</span>, <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span> /* free_and_bufdone_met<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">a_buf</span> */)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>pthread_mutex_unlock(&mMutex)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>}} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {pthread_mutex_lock(&mMutex)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>handleBufferWithLock(buffer, frame_number)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>pthread_mutex_unlock(&mMutex)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span> }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li></ul>

一種是通過循環來進行元數據的批處理,另一種是直接進行元數據的處理,但是批處理最終也是循環調用handleMetadataWithLock來處理:

<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">// QCamera3HWI.cpp void QCamera3HardwareInterface::handleMetadataWithLock(mm_camera_super_buf_t *metadata_buf, bool free_and_bufdone_meta_buf){<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>//Partial result on process_capture_result <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> timestamp<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (urgent_frame_number_valid) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (List<PendingRequestInfo>::iterator i =mPendingRequestsList.begin(); i != mPendingRequestsList.end(); i++) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (i->frame_number == urgent_frame_number &&i->bUrgentReceived == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {camera3_capture_result_t result;memset(&result, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, sizeof(camera3_capture_result_t));i->partial_result_cnt++;i->bUrgentReceived = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;//提取3A數據result.result =translateCbUrgentMetadataToResultMetadata(metadata);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>//對Capture Result進行處理mCallbackOps->process_capture_result(mCallbackOps, &result);//釋放camera_metadata_tfree_camera_metadata((camera_metadata_t *)result.result);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;}}}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (List<PendingRequestInfo>::iterator i = mPendingRequestsList.begin();i != mPendingRequestsList.end() && i->frame_number <= frame_number;) {camera3_capture_result_t result;memset(&result, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, sizeof(camera3_capture_result_t));<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (i->frame_number < frame_number) {//清空數據結構camera3_notify_msg_t notify_msg;memset(&notify_msg, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, sizeof(camera3_notify_msg_t));//定義消息類型notify_msg.type = CAMERA3_MSG_SHUTTER;notify_msg.message.shutter.frame_number = i->frame_number;notify_msg.message.shutter.timestamp = (uint64_t)capture_time (urgent_frame_number - i->frame_number) * NSEC_PER_33MSEC;//調用回調通知應用層發生CAMERA3_MSG_SHUTTER消息mCallbackOps->notify(mCallbackOps, &notify_msg);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>CameraMetadata dummyMetadata;//更新元數據dummyMetadata.update(ANDROID_SENSOR_TIMESTAMP,&i->timestamp, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);dummyMetadata.update(ANDROID_REQUEST_ID,&(i->request_id), <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);//得到元數據釋放結果result.result = dummyMetadata.release();} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {camera3_notify_msg_t notify_msg;memset(&notify_msg, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, sizeof(camera3_notify_msg_t));// Send shutter notify to frameworksnotify_msg.type = CAMERA3_MSG_SHUTTER;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>//從HAL中獲得Metadataresult.result = translateFromHalMetadata(metadata,i->timestamp, i->request_id, i->jpegMetadata, i->pipeline_depth,i->capture_intent);saveExifParams(metadata);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (i->blob_request) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (enabled && metadata->is_tuning_params_valid) {//將Metadata復制到文件dumpMetadataToFile(metadata->tuning_params, mMetaFrameCount, enabled,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Snapshot"</span>,frame_number);}mPictureChannel->queueReprocMetadata(metadata_buf);} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {// Return metadata buffer<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (free_and_bufdone_meta_buf) {mMetadataChannel->bufDone(metadata_buf);free(metadata_buf);}}}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>} }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li></ul>

其中,首先會調用回調的process_capture_result方法來對Capture Result進行處理,然后會調用回調的notify方法來發送一個CAMERA3_MSG_SHUTTER消息,而process_capture_result所對應的實現其實就是Camera3Device的processCaptureResult方法,先分析processCaptureResult:

<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">//Camera3Device.cpp void Camera3Device::processCaptureResult(const camera3_capture_result *result) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>//對于HAL3.2+,如果HAL不支持partial,當metadata被包含在result中時,它必須將partial_result設置為<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>{Mutex::Autolock l(mInFlightLock);ssize_t idx = mInFlightMap.indexOfKey(frameNumber);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>InFlightRequest &request = mInFlightMap.editValueAt(idx);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (result->partial_result != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)request.resultExtras.partialResultCount = result->partial_result;// 檢查結果是否只有partial metadata<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mUsePartialResult && result->result != <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span>) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_2) {//HAL版本高于<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3.2</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (result->partial_result > mNumPartialResults || result->partial_result < <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) {//Log顯示錯誤<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;}isPartialResult = (result->partial_result < mNumPartialResults);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (isPartialResult) {//將結果加入到請求的結果集中request.partialResult.collectedResult.append(result->result);}} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {//低于<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3.2</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (isPartialResult) {// Fire off a 3A-only result <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> possible<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!request.partialResult.haveSent3A) {request.partialResult.haveSent3A =processPartial3AResult(frameNumber,request.partialResult.collectedResult,request.resultExtras);}}}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (result->result != <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span> && !isPartialResult) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (shutterTimestamp == <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {request.pendingMetadata = result->result;request.partialResult.collectedResult = collectedPartialResult;} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {CameraMetadata metadata;metadata = result->result;//發送Capture ResultsendCaptureResult(metadata, request.resultExtras, collectedPartialResult, frameNumber, hasInputBufferInRequest,request.aeTriggerCancelOverride);}}//結果處理好了,將請求移除removeInFlightRequestIfReadyLocked(idx);} // scope <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> mInFlightLock<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span> }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li></ul>

由代碼可知,它會處理局部的或者全部的metadata數據,最后如果result不為空,且得到的是請求處理的全部數據,則會調用sendCaptureResult方法來將請求結果發送出去:

<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">//Camera3Device.cpp void Camera3Device::sendCaptureResult(CameraMetadata &pendingMetadata,CaptureResultExtras &resultExtras,CameraMetadata &collectedPartialResult,uint32_t frameNumber,bool reprocess,const AeTriggerCancelOverride_t &aeTriggerCancelOverride) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (pendingMetadata.isEmpty())//如果數據為空,直接返回<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>CaptureResult captureResult;captureResult.mResultExtras = resultExtras;captureResult.mMetadata = pendingMetadata;//更新metadata<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (captureResult.mMetadata.update(ANDROID_REQUEST_FRAME_COUNT(int32_t*)&frameNumber, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) != OK) {SET_ERR(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Failed to set frame# in metadata (%d)"</span>,frameNumber);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>}// Append any previous partials to form a complete result<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mUsePartialResult && !collectedPartialResult.isEmpty()) {captureResult.mMetadata.append(collectedPartialResult);}//排序captureResult.mMetadata.sort();// Check that there<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'s a timestamp in the result metadatacamera_metadata_entry entry = captureResult.mMetadata.find(ANDROID_SENSOR_TIMESTAMP);...overrideResultForPrecaptureCancel(&captureResult.mMetadata, aeTriggerCancelOverride);// 有效的結果,將其插入BufferList<CaptureResult>::iterator queuedResult =mResultQueue.insert(mResultQueue.end(), CaptureResult(captureResult));...mResultSignal.signal(); }</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li></ul>

最后,它將Capture Result插入了結果隊列,并釋放了結果的信號量,所以到這里,Capture Result處理成功,下面分析前面的notify發送CAMERA3_MSG_SHUTTER消息:

<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">//Camera3Device.cpp void Camera3Device::notify(const camera3_notify_msg *msg) {NotificationListener *listener;{Mutex::Autolock l(mOutputLock);listener = mListener;}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">switch</span> (msg->type) {case CAMERA3_MSG_ERROR: {notifyError(msg->message.error, listener);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;}case CAMERA3_MSG_SHUTTER: {notifyShutter(msg->message.shutter, listener);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;}default:SET_ERR(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Unknown notify message from HAL: %d"</span>,msg->type);} }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li></ul>

它調用了notifyShutter方法:

<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">// Camera3Device.cpp void Camera3Device::notifyShutter(const camera3_shutter_msg_t &msg,NotificationListener *listener) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>// Set timestamp <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> the request <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> the <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>-flight tracking// and get the request ID to send upstream{Mutex::Autolock l(mInFlightLock);idx = mInFlightMap.indexOfKey(msg.frame_number);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (idx >= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {InFlightRequest &r = mInFlightMap.editValueAt(idx);// Call listener, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> any<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (listener != <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span>) {//調用監聽的notifyShutter法國法listener->notifyShutter(r.resultExtras, msg.timestamp);}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>//將待處理的result發送到BuffersendCaptureResult(r.pendingMetadata, r.resultExtras,r.partialResult.collectedResult, msg.frame_number,r.hasInputBuffer, r.aeTriggerCancelOverride);returnOutputBuffers(r.pendingOutputBuffers.array(),r.pendingOutputBuffers.size(), r.shutterTimestamp);r.pendingOutputBuffers.clear();removeInFlightRequestIfReadyLocked(idx);}}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span> }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li></ul>

首先它會通知listener preview成功,最后會調用sendCaptureResult將結果加入到結果隊列。它會調用listener的notifyShutter方法,此處的listener其實是CameraDeviceClient類,所以會調用CameraDeviceClient類的notifyShutter方法:

<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//CameraDeviceClient.cpp</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">void</span> CameraDeviceClient<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::notifyShutter</span>(const CaptureResultExtras<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span> resultExtras,nsecs_t timestamp) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Thread safe. Don't bother locking.</span>sp<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>ICameraDeviceCallbacks<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span> remoteCb <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> getRemoteCallback();<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (remoteCb <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//調用應用層的回調(CaptureCallback的onCaptureStarted方法)</span>remoteCb<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>onCaptureStarted(resultExtras, timestamp);} }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>

此處的ICameraDeviceCallbacks對應的是Java層的CameraDeviceImpl.java中的內部類CameraDeviceCallbacks,所以會調用它的onCaptureStarted方法:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//CameraDeviceImpl.java</span> <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onCaptureStarted</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> CaptureResultExtras resultExtras, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> timestamp) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> requestId = resultExtras.getRequestId();<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> frameNumber = resultExtras.getFrameNumber();<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> CaptureCallbackHolder holder;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">synchronized</span>(mInterfaceLock) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (mRemoteDevice == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Camera already closed</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Get the callback for this frame ID, if there is one</span>holder = CameraDeviceImpl.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.mCaptureCallbackMap.get(requestId);...<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Dispatch capture start notice</span>holder.getHandler().post(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Runnable() {<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">run</span>() {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!CameraDeviceImpl.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.isClosed()) {holder.getCallback().onCaptureStarted(CameraDeviceImpl.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>,holder.getRequest(resultExtras.getSubsequenceId()),timestamp, frameNumber);}}});} }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li></ul>

它會調用OneCameraImpl.java中的mCaptureCallback的onCaptureStarted方法:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//OneCameraImpl.java</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Common listener for preview frame metadata. </span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> CameraCaptureSession.CaptureCallback mCaptureCallback =<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> CameraCaptureSession.CaptureCallback() {<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onCaptureStarted</span>(CameraCaptureSession session,CaptureRequest request, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> timestamp,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> frameNumber) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (request.getTag() == RequestTag.CAPTURE&& mLastPictureCallback != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {mLastPictureCallback.onQuickExpose();}}… }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>

注意:Capture,preview以及autoFocus都是使用的這個回調,而Capture調用的時候,其RequestTag為CAPTURE,而autoFocus的時候為TAP_TO_FOCUS,而preview請求時沒有對RequestTag進行設置,所以回調到onCaptureStarted方法時,不需要進行處理,但是到此時,preview已經啟動成功,可以進行預覽了,其數據都在buffer里。所以到此時,preview的流程全部分析結束,下面給出HAL層上的流程時序圖?

原文地址: http://blog.csdn.net/yangzhihuiguming/article/details/51800587

總結

以上是生活随笔為你收集整理的android6.0源码分析之Camera API2.0下的Preview(预览)流程分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

成人久久18免费 | 精品视频中文字幕 | 成人在线观看影院 | 欧美亚洲久久 | 日韩中午字幕 | 日韩欧美在线一区 | 久久官网 | 成人精品一区二区三区电影免费 | 免费观看的黄色 | 久久亚洲二区 | 免费黄色小网站 | 婷婷六月久久 | 久热香蕉视频 | 日韩三级成人 | av色一区 | 五月在线| 国产精品99在线播放 | 亚洲性少妇性猛交wwww乱大交 | 日本在线成人 | 亚洲午夜久久久综合37日本 | 国产精品青草综合久久久久99 | 精品久久久成人 | 天天色成人 | www.888av | 成人在线网站观看 | 全久久久久久久久久久电影 | 国产视频在线看 | 国产黄色大片 | 黄网站色视频免费观看 | 在线观看免费国产小视频 | 日韩久久久久久久久久久久 | 97色在线视频 | 国产精品福利久久久 | 亚洲精品xxxx| 深夜福利视频在线观看 | 天天综合视频在线观看 | 99国产在线视频 | 久久96| 亚洲va天堂va欧美ⅴa在线 | 欧美嫩草影院 | 日本在线观看一区二区 | 狠狠的干 | 亚洲国产网址 | 高清日韩一区二区 | 超碰在线97免费 | 国产第一页在线播放 | 91x色| 黄色av成人在线观看 | 成人a大片 | 99久久久国产免费 | 婷婷在线不卡 | 成人小电影在线看 | 久久y | 亚洲日韩精品欧美一区二区 | 久久综合久久综合这里只有精品 | 日本在线h| 亚洲日本色 | 亚洲日本在线一区 | 色97在线| 亚洲精品www. | 99热官网 | 91人网站 | 日韩一区二区三免费高清在线观看 | 新版资源中文在线观看 | 91成熟丰满女人少妇 | 波多野结衣精品在线 | 伊人伊成久久人综合网小说 | 免费看黄的| 亚洲成av人片在线观看 | 天天夜夜狠狠操 | 91免费在线视频 | 人人插人人舔 | 日本一区二区三区视频在线播放 | 精品一区二区在线看 | 亚洲小视频在线 | 最新国产精品久久精品 | 91天天操| www激情网 | 国产尤物在线 | 色吊丝在线永久观看最新版本 | 中文字幕av有码 | 最新日韩精品 | 亚洲国产精品va在线看黑人 | www.久久久精品 | 免费合欢视频成人app | 一区二区三区免费网站 | 97碰碰碰| 精品国产电影一区 | 999国产在线 | 深夜福利视频在线观看 | 91中文字幕视频 | 久草在线免费电影 | 亚洲美女在线国产 | 黄色精品免费 | 月丁香婷婷 | 国产免费久久 | 女人高潮一级片 | 国产视频一区二区在线播放 | 中文字幕二区在线观看 | 免费在线观看av网站 | 欧美成年网站 | 成人a免费| 91av在线视频免费观看 | 亚洲h在线播放在线观看h | 国产一区国产二区在线观看 | 天堂久色 | 国产黄a三级三级 | 伊人午夜| 中文字幕欲求不满 | 日韩毛片在线一区二区毛片 | 91插插插免费视频 | 丁香五月亚洲综合在线 | 亚洲综合激情网 | 午夜视频在线观看一区二区三区 | 久久精品一级片 | 久久久91精品国产一区二区精品 | www.啪啪.com| 欧美成人在线免费观看 | 久草在线在线精品观看 | 九九av| 中文字幕4| 国产精品私人影院 | 成人a毛片 | 97在线免费观看 | 黄色片免费电影 | 亚洲精品久久久久久久不卡四虎 | 日韩中字在线观看 | 国产精品18久久久久久久久久久久 | 天天躁日日躁狠狠躁av麻豆 | 超碰成人网| 69av网| 久久视频免费观看 | 在线有码中文 | 久久99深爱久久99精品 | 日韩特黄av| 国产精品久久久久久久久久久免费 | 成人在线一区二区 | 九九九免费视频 | 在线欧美a | 粉嫩av一区二区三区四区 | 精品视频在线看 | 日韩 | 免费观看v片在线观看 | 日韩高清一二三区 | 国产九九九九九 | 久久综合久久综合久久 | 狠狠地操 | 国产精品18久久久久久久网站 | 久久超碰97| 草草草影院 | 欧美日韩国产mv | 高清av免费观看 | 在线成人av | 色婷婷亚洲婷婷 | 人人看人人草 | 97精品国自产拍在线观看 | 人人干在线观看 | 久久久久久久久久久久久影院 | 肉色欧美久久久久久久免费看 | 国内免费久久久久久久久久久 | 久久线视频| 成人免费网站在线观看 | 毛片区 | 国产成年免费视频 | 天天射天天射天天 | www.夜夜夜 | 国产精品久久久久久久毛片 | 在线成人小视频 | 色com| 在线观看av黄色 | 国产最新视频在线观看 | 欧美日韩国产精品一区二区三区 | 久久国产系列 | 91理论片午午伦夜理片久久 | 日韩黄色在线观看 | 午夜精品一二三区 | 91视频黄色| 92国产精品久久久久首页 | 国产一级视频在线观看 | 992tv人人网tv亚洲精品 | 色偷偷av男人天堂 | 成人电影毛片 | 丁香狠狠 | 9在线观看免费高清完整 | 插插插色综合 | 国产精品一区免费在线观看 | 国产精品第一视频 | a午夜在线 | 中文字幕中文字幕中文字幕 | 国产精品毛片一区 | 久草在线中文888 | 三级av在线免费观看 | 97人人艹 | 国产亚洲欧美一区 | 一区二区三区动漫 | 精品一区二区三区久久久 | 在线中文字幕网站 | 欧美激情第十页 | 久色小说 | 国产精品av免费观看 | av在线电影网站 | 日韩视频一区二区三区在线播放免费观看 | 久久6精品 | 亚洲成av人电影 | 国产精品久久久久9999 | 亚洲欧美精品一区 | 国内揄拍国产精品 | 欧美在线资源 | 久久人91精品久久久久久不卡 | 精品美女在线视频 | 成人黄色在线视频 | 在线播放第一页 | 久久avav| 日韩 国产 | 香蕉视频在线看 | 综合色婷婷 | 国产精品 999 | 黄色特级毛片 | 99免费在线视频 | www国产一区 | 最近2019好看的中文字幕免费 | 久久99久久99精品免费看小说 | 国产青青青 | 天天操天天干天天操天天干 | 一区二区三区四区精品 | 亚洲综合婷婷 | 五月婷婷综合激情网 | 亚洲日本va午夜在线影院 | 天天射天天爽 | 丁香六月在线 | 日躁夜躁狠狠躁2001 | 人人爽人人插 | 欧美精品久久久久 | 日韩激情三级 | 天天操天天谢 | 特级片免费看 | 精品国产区在线 | 91在线免费视频观看 | 午夜三级大片 | 中文字幕亚洲综合久久五月天色无吗'' | 狠狠狠色丁香婷婷综合久久五月 | 九九免费视频 | 欧美成人tv | 伊人亚洲综合网 | 韩日av在线 | 国产亚洲精品久久网站 | 在线观看免费一区 | 日本精品在线 | 激情欧美国产 | 另类五月激情 | 国产精品视频app | 99人久久精品视频最新地址 | 亚洲综合网 | 日日夜操 | 视频福利在线 | 欧美一区二区三区在线播放 | 久久9999久久 | 在线欧美a | 91超国产 | 有码中文字幕 | 手机av电影在线 | 国产亚洲精品久久久久久 | 黄色网在线免费观看 | 久久综合国产伦精品免费 | 麻豆av一区二区三区在线观看 | 伊人网综合在线观看 | 成人在线视频免费 | 久久久受www免费人成 | 日韩三级不卡 | 午夜精品久久久久久久99 | 久久久久久黄色 | japanesefreesex中国少妇 | 亚洲激情电影在线 | 欧美韩日视频 | 欧美精品做受xxx性少妇 | 人人澡人人爽欧一区 | 97视频网站 | av性在线| 婷婷久久亚洲 | 日本三级久久久 | 美女免费黄网站 | 麻豆传媒视频观看 | 在线免费观看视频 | 三级免费黄 | 顶级bbw搡bbbb搡bbbb| 热久久免费视频 | 久久久精品二区 | 久产久精国产品 | 精品国产一区二区三区四 | 99爱这里只有精品 | 国产视 | 国产精品久久久久一区二区三区共 | 国产精品久久一卡二卡 | 日韩最新在线 | 女女av在线 | 九精品 | 日韩av中文在线 | av一区二区在线观看中文字幕 | 91麻豆精品国产 | 97福利在线观看 | 在线看污网站 | 亚洲精品h | 中文字幕黄色网 | a亚洲视频 | 中文字幕日韩国产 | 右手影院亚洲欧美 | 国产高清视频免费最新在线 | 黄色一级在线观看 | 一区二区电影在线观看 | 久久久精品二区 | 欧洲亚洲国产视频 | 天天天色综合 | www黄色com | 九七人人干 | 在线观看国产91 | 激情在线免费视频 | 中文字幕丝袜制服 | 午夜免费电影院 | 在线免费观看的av网站 | 99精品视频中文字幕 | 亚洲美女视频在线观看 | 国产精品亚洲精品 | 不卡的av电影| www黄色软件 | 国产精品久久99 | 9999精品视频 | 天天躁日日躁狠狠躁av中文 | 国产精品自产拍在线观看 | 日韩精品一区二区三区视频播放 | 射综合网| 日韩在线国产精品 | 91福利小视频 | 丁香花在线观看免费完整版视频 | 国产无遮挡又黄又爽在线观看 | 伊人成人久久 | 久久久久国产一区二区三区 | 片网址| 中文字幕在线观看播放 | 天天操天天射天天插 | 国产福利91精品张津瑜 | x99av成人免费 | 日韩欧美99| 国产粉嫩在线观看 | 婷婷激情在线 | 亚洲国产午夜精品 | 日韩欧美国产成人 | 97免费公开视频 | av中文字幕在线看 | 国产专区在线视频 | 人人干干人人 | 国产999精品视频 | 亚洲视频免费在线看 | 中文字幕在线视频第一页 | 91精品人成在线观看 | 欧美精品一区二区免费 | 精品久久久免费视频 | 91爱爱电影 | 97超碰在线资源 | 91福利社区在线观看 | 中文字幕在线有码 | av成人免费观看 | 中文字幕一区二区在线播放 | 中文字幕av在线播放 | 丁香五月网久久综合 | av丁香| 18久久久久久 | av网址在线播放 | 欧美精品免费在线观看 | 九九99靖品 | 国内精品久久久久久久影视麻豆 | 久久国产精品一区二区三区四区 | 97超级碰碰碰碰久久久久 | 日韩在线观看的 | av高清一区二区三区 | 韩国三级一区 | 久久精品女人毛片国产 | va视频在线观看 | 91免费试看 | 日韩视频在线观看免费 | 中文字幕免费成人 | 在线a亚洲视频播放在线观看 | 色a在线观看 | 在线三级av | 国产精品美女 | 中文字幕在线播放一区 | 黄色一级在线免费观看 | 最新日韩视频 | 国产精品12 | 香蕉久久久久久av成人 | 99精品视频免费全部在线 | 午夜av片 | 天天色天天综合网 | 麻豆91小视频 | 久久久久久久久久久福利 | 日日夜夜噜噜噜 | 日本精品久久久久 | 特级a毛片 | 国产成人亚洲在线观看 | 国产午夜精品免费一区二区三区视频 | 一级性av| 欧美日韩另类在线观看 | 午夜精品久久久久久久99无限制 | 久久久久久国产一区二区三区 | 日韩视频免费观看高清完整版在线 | 五月激情丁香图片 | 日日操日日插 | 五月婷婷六月丁香在线观看 | 亚洲欧美在线视频免费 | 国产在线欧美 | 国产精品久久久久久久久岛 | 久久69精品久久久久久久电影好 | 成人在线视频免费看 | 91av在线免费播放 | 在线 你懂 | 在线观看免费av网站 | 久久性生活片 | 色婷婷a | 在线播放 亚洲 | 日韩激情av在线 | 人人插人人做 | 国产精品视频全国免费观看 | 国产精品久久99综合免费观看尤物 | 91中文在线视频 | 精品国产乱码久久久久久1区2匹 | 天天操天天爱天天干 | 日韩免费精品 | 久久最新网址 | 成人av中文字幕在线观看 | 五月婷婷开心中文字幕 | 久久99精品久久久久久秒播蜜臀 | av在线h| 精品久久1| 中文字幕av全部资源www中文字幕在线观看 | 欧美伦理电影一区二区 | 成人免费xyz网站 | 婷婷 综合 色 | 亚洲成a人片77777潘金莲 | 岛国一区在线 | 久操久 | 五月激情在线 | 久久视频这里有久久精品视频11 | 波多野结衣一区 | 在线观看香蕉视频 | 天天操天天透 | 国产亲近乱来精品 | 国产在线欧美日韩 | 国产免费观看高清完整版 | 高清在线一区 | 亚洲色影爱久久精品 | 99r在线观看 | 精品国产乱码久久久久久1区二区 | 四虎影视精品永久在线观看 | 亚洲成av人片在线观看www | 在线成人欧美 | 亚洲影音先锋 | 在线视频一二区 | 国产中文字幕一区 | 久久精品成人 | 国产高清无线码2021 | 免费日韩一区二区 | 国产又粗又猛又色又黄网站 | 91免费看黄 | 亚洲在线视频网站 | 在线激情小视频 | 91尤物在线播放 | 在线播放你懂 | 午夜av网站 | 五月婷婷丁香 | 国产视频二区三区 | 夜夜操网站 | 日韩电影在线观看一区二区三区 | 黄色看片 | www国产亚洲精品 | 成人国产亚洲 | 亚洲国产美女精品久久久久∴ | 日韩黄色av网站 | 日韩一级黄色av | 92av视频| 在线日韩 | 国产经典av| 久久国产经典视频 | 中文字幕在线第一页 | 久久久2o19精品 | 免费三级在线 | 日本中文字幕网 | av在线播放国产 | 久久乐九色婷婷综合色狠狠182 | 美女视频黄频大全免费 | 久久国色夜色精品国产 | 国产黄色免费电影 | 国产免费中文字幕 | 国产免费成人 | 精品亚洲欧美无人区乱码 | 亚洲欧美日本一区二区三区 | 国产97碰免费视频 | 日韩av免费一区二区 | 亚洲日本精品 | 99久久久久久久久久 | 午夜精品久久久久久久99热影院 | 日韩免费视频一区二区 | 日韩美女黄色片 | 狠狠艹夜夜干 | 久久麻豆视频 | 日韩av一区二区三区四区 | 国产视频一区二区在线观看 | 中文字幕最新精品 | 手机成人av | 91精品久| 成人va在线观看 | 黄色软件视频网站 | 国产精品不卡视频 | 国产不卡在线播放 | 久久久91精品国产一区二区三区 | 久久经典视频 | 亚洲五月花 | av黄色在线播放 | 99热最新| 久久亚洲欧美 | 97超视频 | 亚洲一区二区三区毛片 | 亚洲在线a | 日韩极品视频在线观看 | 美女网站视频色 | 欧美二区三区91 | 热久久免费视频 | 免费看色的网站 | 欧美精品xxx | 亚洲天天做 | 成人午夜电影久久影院 | 国产精华国产精品 | 欧美日韩国产一区二区在线观看 | 少妇性色午夜淫片aaaze | 黄色天堂在线观看 | 色大片免费看 | 日本一区二区三区免费观看 | 国精产品一二三线999 | 国产成免费视频 | 国产精品久久99精品毛片三a | 国产日产高清dvd碟片 | 亚洲精品国产自产拍在线观看 | av3级在线| av中文字幕网 | 日韩电影中文字幕在线观看 | 欧美成人手机版 | 国产精品私人影院 | 亚洲经典中文字幕 | 国产欧美精品在线观看 | 国产黄色片免费观看 | 亚洲少妇自拍 | 亚洲黄色软件 | 丰满少妇一级片 | 欧美久久久久久久久久久久久 | 亚洲日本色 | 亚洲视频www | 日韩高清毛片 | 国产中文| 久久久久二区 | 日韩动漫免费观看高清完整版在线观看 | 久久久一本精品99久久精品66 | 精品一区二区在线看 | 国产一区二区高清视频 | 日本不卡一区二区 | 91网免费看| 丝袜美腿在线视频 | 欧美污网站| 日日日日干 | 国产精品成人免费一区久久羞羞 | 午夜久久福利影院 | 国产精品久久伊人 | 麻豆国产电影 | 亚洲午夜精品在线观看 | 久久久久婷 | 91天堂在线观看 | 九九免费精品视频 | 一区二区三区动漫 | 国产91亚洲精品 | 免费美女av | 九九在线视频免费观看 | 日本一区二区高清不卡 | 精品在线观看免费 | 国产成人精品久久二区二区 | 人人超在线公开视频 | 亚洲伊人第一页 | 国产一区二区精品久久91 | 国产精品久久久久久久久费观看 | 久久伊人八月婷婷综合激情 | 成人精品99| 九九热在线观看 | 久久男人中文字幕资源站 | 免费a视频 | 日韩 在线观看 | 久久国产精品久久精品 | 精品日韩视频 | 在线看毛片网站 | 中文字幕网站视频在线 | 精品久久久久久国产偷窥 | 91夫妻视频 | 99在线观看精品 | 一本到视频在线观看 | 热久久免费视频精品 | 国产无遮挡又黄又爽在线观看 | 新版资源中文在线观看 | 天天射日| 午夜久久电影网 | 久久国产精品99国产 | 69久久久| 中文字幕一区二区三区四区 | 精品视频网站 | 亚洲精品国产视频 | 欧美日韩国产网站 | 人人射人人爱 | 国产色在线观看 | 米奇狠狠狠888 | 国产免费一区二区三区最新 | 国产美女在线精品免费观看 | 青青视频一区 | 韩国av免费在线 | 日本不卡一区二区 | 欧美精品国产综合久久 | 美女久久久久久久久久 | 九九久久免费视频 | 丁香影院在线 | 久久99久国产精品黄毛片入口 | 中文字幕丰满人伦在线 | 中文字幕av在线播放 | 久久久99国产精品免费 | 中国一级特黄毛片大片久久 | 久久影院亚洲 | 日日爽视频| 黄色日视频 | 天天色.com | 91精品在线播放 | 国产精品毛片一区二区在线 | 五月丁婷婷 | 午夜视频一区二区三区 | 1区2区3区在线观看 三级动图 | 国产精品一区二区在线免费观看 | 丁香激情综合 | 白丝av免费观看 | 国内精品久久久久久久97牛牛 | av爱干| 亚洲视频在线看 | 黄色一级免费网站 | 色com网 | 日韩欧美精品一区 | 午夜精品视频在线 | 国产高清在线免费观看 | 97在线公开视频 | 中文av一区二区 | 欧美怡红院| 日韩av电影中文字幕 | 四虎免费在线观看视频 | 开心综合网 | 久久九九国产视频 | 中文字幕人成人 | 久久国产免费 | 国产一线二线三线在线观看 | 久久综合色8888 | 麻豆精品视频在线 | 美女免费网站 | 日韩免费在线一区 | 天堂网一区二区 | 九色视频网 | 在线视频91 | 日韩美av在线 | 色视频网址 | av午夜电影 | 日韩av影视 | 国产高清综合 | 五月婷婷伊人网 | 五月婷婷欧美 | 色婷婷综合久色 | 久久午夜精品影院一区 | 91成人精品一区在线播放69 | 久久9精品 | 丁香花五月 | 婷婷色狠狠 | 我要看黄色一级片 | 91香蕉视频污在线 | 香蕉视频91 | 久久曰视频 | 91色网址| 99久久久久久久 | 天天夜夜亚洲 | 91看片在线播放 | 成人中文字幕+乱码+中文字幕 | 成人中文字幕+乱码+中文字幕 | 欧美午夜精品久久久久久浪潮 | 国产资源在线播放 | 亚洲码国产日韩欧美高潮在线播放 | 国产精品免费观看视频 | 久久精品免视看 | 成人va天堂 | 国产另类xxxxhd高清 | 国产精品久久一区二区无卡 | 天天操天天谢 | 中文字幕在线视频第一页 | 一级黄色片在线免费观看 | 在线99视频 | 91成人精品一区在线播放 | 国产黄av | a视频免费在线观看 | 黄色电影小说 | 亚洲国产97在线精品一区 | 日韩中文字幕免费视频 | 91精品国产欧美一区二区成人 | 久久久久人人 | 国产午夜精品免费一区二区三区视频 | 综合婷婷丁香 | 国产资源站 | 色婷婷激情电影 | 国产欧美日韩一区 | 日韩系列在线 | 亚洲狠狠丁香婷婷综合久久久 | 亚洲激情在线视频 | 欧美极品少妇xxxxⅹ欧美极品少妇xxxx亚洲精品 | 国产精品久久免费看 | 国产精品成人国产乱一区 | 日韩在线一区二区免费 | 欧美黑人xxxx猛性大交 | 中文字幕国产精品一区二区 | 精品在线播放 | 欧美日韩精品在线一区二区 | 久久国产精品电影 | 日日操天天操夜夜操 | 成人wwwxxx视频 | 免费特级黄色片 | 国产在线色视频 | 日韩视频在线观看免费 | 91视频啪| 九九久久久久久久久激情 | 欧美日韩精品免费观看视频 | 在线观看视频中文字幕 | 国产成人综合图片 | 超碰人人乐 | 99视频99 | 中文在线a√在线 | 高清av中文字幕 | 午夜精品久久 | 免费在线国产视频 | 黄色av成人在线 | 亚洲精品成人av在线 | 黄色小说免费观看 | 久久av电影| 精品久久网站 | 久久久久久久久免费视频 | 国产精品一区二区在线 | 成人在线观看免费视频 | 日韩精品视频在线免费观看 | 天天色天天上天天操 | 精品久久久久久久久久久久久久久久 | 超碰97人人在线 | 国产裸体视频网站 | 国产91探花 | 中文字幕不卡在线88 | 日韩精品免费一区二区 | 欧美另类xxxxx | 成年人在线电影 | 国产最顶级的黄色片在线免费观看 | 天天色天 | 成人免费电影 | 久久99亚洲精品久久 | 日本免费一二三区 | 五月天婷婷在线观看视频 | 久久综合给合久久狠狠色 | 国产精品毛片久久久 | 国产成人亚洲在线观看 | 久久国产美女 | 激情综合中文娱乐网 | www.狠狠色.com| 欧美另类xxxxx | 成人av资源网站 | 天天爱天天操 | 91在线中字| 中文字幕无吗 | 国产成人一区二区啪在线观看 | 久久草网站 | 一级黄色a视频 | 网站你懂的 | 国产一区二区影院 | 成人小视频在线观看免费 | 成人av网址大全 | 国产亚洲va综合人人澡精品 | 亚洲精品乱码久久久久久高潮 | 久久精品日产第一区二区三区乱码 | 福利久久 | 欧美一级黄大片 | 一区二区三区高清 | 欧美精品一区在线发布 | 久久久久久国产精品久久 | 色婷婷av一区二 | 中文字幕在线专区 | 久久高清视频免费 | 五月婷婷六月丁香激情 | 91热爆在线观看 | 国产精品久久久久久久久婷婷 | 黄网站免费久久 | 亚洲精品中文字幕视频 | 久久夜夜操 | 亚洲精品国偷拍自产在线观看 | 人人超碰97| 中文字幕亚洲字幕 | 麻豆免费在线视频 | 久久在线| 日日干美女 | av资源免费看 | 91黄色影视 | 日本成人黄色片 | 91.麻豆视频 | 91视频久久久 | 香蕉视频啪啪 | 99视频精品免费视频 | 狠狠狠狠狠狠操 | 中文字幕亚洲综合久久五月天色无吗'' | 男女拍拍免费视频 | 久久激情综合网 | 亚洲国产精久久久久久久 | 久久免费视频8 | 在线观看成人网 | 日日躁夜夜躁aaaaxxxx | 91在线免费视频 | 久久精品欧美一 | 亚洲国产精品成人va在线观看 | 丁香六月伊人 | 丁香婷婷综合五月 | 欧美 激情 国产 91 在线 | 最近免费中文字幕mv在线视频3 | 国产视频久久 | 欧美另类视频 | av成人在线网站 | 一区二区免费不卡在线 | 亚洲高清在线观看视频 | 精品91久久久久 | 五月天色综合 | 亚洲国产成人精品在线观看 | 久久8 | 国产手机av在线 | 日韩精品一区二区电影 | 免费看的黄色片 | 国产精品女同一区二区三区久久夜 | 狠狠干在线 | 欧美日韩在线精品一区二区 | 国产女人40精品一区毛片视频 | 成人免费视频播放 | 天天操天天操天天操 | 日韩欧美一区二区在线 | 国产日韩在线播放 | 夜夜婷婷 | 欧美大片mv免费 | 狠狠色狠狠色终合网 | 国产精品综合久久久 | 天天爽夜夜爽人人爽一区二区 | 99精品黄色片免费大全 | 天堂素人在线 | 日韩电影一区二区三区在线观看 | 日韩女同av | 成人观看视频 | 国产一级高清 | 99热都是精品 | 一区二区三区四区五区在线视频 | 欧美日韩在线网站 | 亚洲国产一区在线观看 | 国产小视频在线观看免费 | 福利一区二区三区四区 | 婷婷香蕉 | 全久久久久久久久久久电影 | 正在播放 久久 | 国产精品女教师 | 日韩午夜小视频 | 亚洲欧美婷婷六月色综合 | 免费观看性生交 | sm免费xx网站 | 日韩在线观看网址 | 三级av免费看| 黄色资源在线观看 | 国产亚洲成人网 | 日韩在线观看第一页 | 亚洲一级片免费观看 | 久久综合福利 | 涩涩网站在线观看 | 国产第页 | 日本精品视频在线观看 | 狠狠天天 | 麻豆国产在线播放 | 中文字幕日韩高清 | 一本一本久久a久久精品综合 | 精品a视频 | 九色精品免费永久在线 | 国产精品久久久久久久久久免费看 | 久草在线精品观看 | 99国内精品 | 精品国产色 | 久久高清免费 | 2022国产精品视频 | 国产中文字幕在线播放 | 一区二区成人国产精品 | 亚洲精品午夜一区人人爽 | 永久免费av在线播放 | 激情五月***国产精品 | 亚洲精品综合久久 | 中字幕视频在线永久在线观看免费 | 青青草在久久免费久久免费 | 久久av伊人 | 91亚州| 免费色网| 欧美黑人猛交 | 特黄特色特刺激视频免费播放 | 五月婷婷中文网 | 在线观看一二三区 | 91在线国产观看 | 男女激情网址 | 日韩区欠美精品av视频 | 国产精品久久久久久久久久久久午夜 | 国产精品福利无圣光在线一区 | 国产二区视频在线 | 欧美国产日韩在线观看 | 日本黄网站 | 夜夜躁日日躁 | 天天干天天射天天插 | 婷婷丁香色综合狠狠色 | 久久综合综合久久综合 | 日韩精品久久久久 | 国产日产精品久久久久快鸭 | 欧美在线观看小视频 | 黄色免费观看视频 | 国产乱码精品一区二区三区介绍 | 视频一区二区在线观看 | 久久天天躁狠狠躁夜夜不卡公司 | www.xxx.性狂虐 | 狠狠操综合 | 午夜久久久久 | 在线免费高清一区二区三区 | 五月婷婷在线观看视频 | 久久精品99| av超碰免费在线 | 国产91全国探花系列在线播放 | wwwwww黄| 日日夜夜天天人人 | 人人添人人澡 | 国内精品久久久 | 中文字幕日韩一区二区三区不卡 | 国产精品乱码久久 | 日韩二三区| 伊人天堂网 | 97精品在线 | 日韩午夜精品 | 国产91大片 | 国产一级视屏 | 日韩一区在线免费观看 | 欧美日韩国产一区二区在线观看 | 精品国产色 | 欧美另类激情 | 一级α片免费看 | 亚洲女同videos | 91精品一区二区三区久久久久久 | 久久成电影 | 91伊人久久大香线蕉蜜芽人口 | 中文字幕在线播放第一页 | 高清视频一区二区三区 | 欧美精品久久久久久久亚洲调教 | 久久 一区 | 黄色av一级片 | 一区二区成人国产精品 | 91麻豆产精品久久久久久 | 久草免费在线视频 | 亚洲精品视频在线看 | 日韩视频一区二区三区 | 日韩电影在线观看一区二区三区 | 久久亚洲精品国产亚洲老地址 | 91精品免费看 | 国产精久久久久久妇女av | 色干干 | 999视频在线播放 | 麻豆影视在线免费观看 | 成人中文字幕av | 亚洲精品在线观看中文字幕 | 天天干夜夜夜 | 精品一区二区三区香蕉蜜桃 | 97精产国品一二三产区在线 | 亚洲一片黄 | 97影视 | 久久久久综合网 | 胖bbbb搡bbbb擦bbbb | 国产精久久久久久妇女av | 精品特级毛片 | 久久爽久久爽久久av东京爽 | 免费看黄网站在线 | 精品国产自在精品国产精野外直播 | 国色天香在线观看 | 久章操 | 成人av网站在线播放 | 久热电影 | 99九九99九九九视频精品 | a午夜在线 | 一区二区三区视频网站 | 在线观看一区二区精品 | 欧美日韩高清一区 | 日韩成人邪恶影片 |