• Android Camera App启动流程解析


    前言:做了7年的camera app开发,给自己一个总结,算是对camera的一次告白吧。Camera被大家誉为手机的眼睛,是现在各大手机厂商的卖点,也是各大厂商重点发力的地方。Camera的重要性我就不在这里赘述了,让我们进入正题。

    先来一张官方的流程图,让我们更加清晰的了解Camera的架构。

    请添加图片描述
    请添加图片描述

    一、申请权限

    Manifest.permission.CAMERA

    如果只要拍照功能,不需要录像的功能,只申请Camera的权限就可以了。
    参考代码:参考Camera2 原码

    1. Manifest.permission.RECORD_AUDIO

    如果camera app中需要有录像的功能
    参考代码:参考Camera2 原码

    2. Manifest.permission.ACCESS_COARSE_LOCATION

    3. Manifest.permission.ACCESS_FINE_LOCATION

    如果需要拍照生成的照片带gps的信息,需要申请这两个权限。
    参考代码:参考Camera2 原码

    二、准备SurfaceView或者SurfaceTexture 或 TextureView

    在Camera app启动的时候,onCreate的时候创建surface,可以选择SurfaceView或者SurfaceTexture,这里是根据业务选择的,各有优缺点。

    • SurfaceView:SurfaceView的核心在于提供了两个线程:UI线程和渲染线程,两个线程通过“双缓冲”机制来达到高效的界面刷新效果。
    • SurfaceTexture: 和SurfaceView不同的是,它对图像流的处理并不直接显示,而是转为GL外部纹理,因此可用于图像流数据的二次处理(如Camera滤镜,桌面特效等)。比如Camera的预览数据,变成纹理后可以交给GLSurfaceView直接显示,也可以通过SurfaceTexture交给TextureView作为View heirachy中的一个硬件加速层来显示。
    • TextureView: 它可以将内容流直接投影到View中,可以用于实现Live preview等功能。和SurfaceView不同,它不会在WMS中单独创建窗口,而是作为View hierachy中的一个普通View,因此可以和其它普通View一样进行移动,旋转,缩放,动画等变化。
    • SurfaceView和TextureView对比:
      请添加图片描述
      参考代码:Camera2 代码中用的是SurefaceTexture

    三、准备打开camera和预览

    Surface准备好了,收到onSurfaceTextureAvailable后,app就可以打开camera和预览了。
    参考代码:reopenCamera

    1. 获取camera id

    首先要确定app要打开的是哪个Camera id,把这个id确定好,app就可以通过openCamera来打开正确的camera sensor了。
    参见camera2代码:获取cameraid

    2. openCamera

    CameraManager调用openCamera方法打开camera,参见api文档:openCamera
    对应到Camera2 的原码位置:open —> 真正调用openCamera的位置 -->framework中CameraManager调用openCamera的位置–>openCameraForUid -->openCameraDeviceUserAsync–>connectDevice–>connectHelper–>CameraService.cpp中的方法connectHelper–>makeClient

    1060      if (effectiveApiLevel == API_1) { // Camera1 API route
    1061          sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
    1062          *client = new Camera2Client(cameraService, tmp, cameraService->mCameraServiceProxyWrapper,
    1063                  packageName, featureId, cameraId, api1CameraId, facing, sensorOrientation,
    1064                  clientPid, clientUid, servicePid, overrideForPerfClass, overrideToPortrait,
    1065                  forceSlowJpegMode);
    1066          ALOGI("%s: Camera1 API (legacy), override to portrait %d, forceSlowJpegMode %d",
    1067                  __FUNCTION__, overrideToPortrait, forceSlowJpegMode);
    1068      } else { // Camera2 API route
    1069          sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
    1070                  static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
    1071          *client = new CameraDeviceClient(cameraService, tmp,
    1072                  cameraService->mCameraServiceProxyWrapper, packageName, systemNativeClient,
    1073                  featureId, cameraId, facing, sensorOrientation, clientPid, clientUid, servicePid,
    1074                  overrideForPerfClass, overrideToPortrait);
    1075          ALOGI("%s: Camera2 API, override to portrait %d", __FUNCTION__, overrideToPortrait);
    1076      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    几种常见的camera连接的错误,这些错误是客户端调用initialize,调用到服务端,服务端返回的错误信息。

    1858          String8 monitorTags = isClientWatched(client.get()) ? mMonitorTags : String8("");
    1859          err = client->initialize(mCameraProviderManager, monitorTags);
    1860          if (err != OK) {
    1861              ALOGE("%s: Could not initialize client from HAL.", __FUNCTION__);
    1862              // Errors could be from the HAL module open call or from AppOpsManager
    1863              switch(err) {
    1864                  case BAD_VALUE:
    1865                      return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
    1866                              "Illegal argument to HAL module for camera \"%s\"", cameraId.string());
    1867                  case -EBUSY:
    1868                      return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
    1869                              "Camera \"%s\" is already open", cameraId.string());
    1870                  case -EUSERS:
    1871                      return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
    1872                              "Too many cameras already open, cannot open camera \"%s\"",
    1873                              cameraId.string());
    1874                  case PERMISSION_DENIED:
    1875                      return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
    1876                              "No permission to open camera \"%s\"", cameraId.string());
    1877                  case -EACCES:
    1878                      return STATUS_ERROR_FMT(ERROR_DISABLED,
    1879                              "Camera \"%s\" disabled by policy", cameraId.string());
    1880                  case -ENODEV:
    1881                  default:
    1882                      return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
    1883                              "Failed to initialize camera \"%s\": %s (%d)", cameraId.string(),
    1884                              strerror(-err), err);
    1885              }
    1886          }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    –>调用camera2的CameraDeviceClient -->Camera2ClientBase.

    switch (providerTransport) {
    116          case IPCTransport::HIDL:
    117              mDevice =
    118                      new HidlCamera3Device(TClientBase::mCameraIdStr, mOverrideForPerfClass,
    119                              mLegacyClient);
    120              break;
    121          case IPCTransport::AIDL:
    122              mDevice =
    123                      new AidlCamera3Device(TClientBase::mCameraIdStr, mOverrideForPerfClass,
    124                              mLegacyClient);
    125               break;
    126          default:
    127              ALOGE("%s Invalid transport for camera id %s", __FUNCTION__,
    128                      TClientBase::mCameraIdStr.string());
    129              return NO_INIT;
    130      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    –>Camera2ClientBase.cpp 中的方法 initialize --> HidlCamera3Device.cpp 中的方法initialize -->openHidlSession --> open

    714  status_t CameraProviderManager::openHidlSession(const std::string &id,
    715          const sp<device::V3_2::ICameraDeviceCallback>& callback,
    716          /*out*/
    717          sp<device::V3_2::ICameraDeviceSession> *session) {
    718  
    719      std::lock_guard<std::mutex> lock(mInterfaceMutex);
    720  
    721      ... ...
    723  
    724      auto *hidlDeviceInfo3 = static_cast<HidlProviderInfo::HidlDeviceInfo3*>(deviceInfo);
    725      sp<ProviderInfo> parentProvider = deviceInfo->mParentProvider.promote();
    726      if (parentProvider == nullptr) {
    727          return DEAD_OBJECT;
    728      } // 获取cameraProvider的sp
    729      const sp<provider::V2_4::ICameraProvider> provider =
    730              static_cast<HidlProviderInfo *>(parentProvider.get())->startProviderInterface();
    731      if (provider == nullptr) {
    732          return DEAD_OBJECT;
    733      }
    734      std::shared_ptr<HalCameraProvider> halCameraProvider =
    735              std::make_shared<HidlHalCameraProvider>(provider, provider->descriptor);
    736      saveRef(DeviceMode::CAMERA, id, halCameraProvider);
    737     ... ...
    744      //打开camera的真正的方法,调用到hal层打开camera的设备节点
    745      ret = interface->open(callback, [&status, &session]
    746              (Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
    747                  status = s;
    748                  if (status == Status::OK) {
    749                      *session = cameraSession;
    750                  }
    751              });
    752      if (!ret.isOk()) {
    753          removeRef(DeviceMode::CAMERA, id);
    754          ALOGE("%s: Transaction error opening a session for camera device %s: %s",
    755                  __FUNCTION__, id.c_str(), ret.description().c_str());
    756          return DEAD_OBJECT;
    757      }
    758      return HidlProviderInfo::mapToStatusT(status);
    759  }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    这个open方法会调用hal的open方法,打开对应的camera设备节点,得到返回值fd,判断是否打开成功。

    3. Camera open 成功后,app就可以创建session了

    我们还是以Camera2的代码为例:camera.startPreview --> 调用OneCameraImpl.java的startPreview --> setupAsync --> setup --> mDevice.createCaptureSession() 调用api创建session.–> 设置预览repeatingPreview

    429      @Override
    430      public void startPreview(Surface previewSurface, CaptureReadyCallback listener) {
    431          mPreviewSurface = previewSurface;
    432          setupAsync(mPreviewSurface, listener);
    433      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    527      private void setupAsync(final Surface previewSurface, final CaptureReadyCallback listener) {
    528          mCameraHandler.post(new Runnable() {
    529              @Override
    530              public void run() {
    531                  setup(previewSurface, listener);
    532              }
    533          });
    534      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    543      private void setup(Surface previewSurface, final CaptureReadyCallback listener) {
    544          try {
    545              if (mCaptureSession != null) {
    546                  mCaptureSession.abortCaptures();
    547                  mCaptureSession = null;
    548              }
    549              List<Surface> outputSurfaces = new ArrayList<Surface>(2);
    550              outputSurfaces.add(previewSurface);
    551              outputSurfaces.add(mCaptureImageReader.getSurface());
    552  
    553              mDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
    554  
    555                  @Override
    556                  public void onConfigureFailed(CameraCaptureSession session) {
    557                      listener.onSetupFailed();
    558                  }
    559  
    560                  @Override
    561                  public void onConfigured(CameraCaptureSession session) {
    562                      mCaptureSession = session;
    563                      mAFRegions = ZERO_WEIGHT_3A_REGION;
    564                      mAERegions = ZERO_WEIGHT_3A_REGION;
    565                      mZoomValue = 1f;
    566                      mCropRegion = cropRegionForZoom(mZoomValue);
    567                      boolean success = repeatingPreview(null);
    568                      if (success) {
    569                          listener.onReadyForCapture();
    570                      } else {
    571                          listener.onSetupFailed();
    572                      }
    573                  }
    574  
    575                  @Override
    576                  public void onClosed(CameraCaptureSession session) {
    577                      super.onClosed(session);
    578                  }
    579              }, mCameraHandler);
    580          } catch (CameraAccessException ex) {
    581              Log.e(TAG, "Could not set up capture session", ex);
    582              listener.onSetupFailed();
    583          }
    584      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    611      private boolean repeatingPreview(Object tag) {
    612          try {
    613              CaptureRequest.Builder builder = mDevice.
    614                      createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
    615              builder.addTarget(mPreviewSurface);
    616              builder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
    617              addBaselineCaptureKeysToRequest(builder);
    618              mCaptureSession.setRepeatingRequest(builder.build(), mCaptureCallback,
    619                      mCameraHandler);
    620              Log.v(TAG, String.format("Sent repeating Preview request, zoom = %.2f", mZoomValue));
    621              return true;
    622          } catch (CameraAccessException ex) {
    623              Log.e(TAG, "Could not access camera setting up preview.", ex);
    624              return false;
    625          }
    626      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    4. framework层createCaptureSession的流程

    CameraDevice.java --> createCaptureSession --> CameraDeviceImpl.java -->createCaptureSession --> createCaptureSessionInternal --> configureStreamsChecked -->

    553      public void createCaptureSession(List<Surface> outputs,
    554              CameraCaptureSession.StateCallback callback, Handler handler)
    555              throws CameraAccessException {
    556          List<OutputConfiguration> outConfigurations = new ArrayList<>(outputs.size());
    557          for (Surface surface : outputs) {
                     // 把surface赋值给OutputConfiguration中的ArrayList,
                     // OutConfigurations 就是framework进程和cameraservice进程通信传递的对象。
                     // public final class OutputConfiguration implements Parcelable
    558              outConfigurations.add(new OutputConfiguration(surface));
    559          }
    560          createCaptureSessionInternal(null, outConfigurations, callback,
    561                  checkAndWrapHandler(handler), /*operatingMode*/ICameraDeviceUser.NORMAL_MODE,
    562                  /*sessionParams*/ null);
    563      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    432      public boolean configureStreamsChecked(InputConfiguration inputConfig,
    433              List<OutputConfiguration> outputs, int operatingMode, CaptureRequest sessionParams,
    434              long createSessionStartTime)
    435                      throws CameraAccessException {
    436          // Treat a null input the same an empty list
    437          if (outputs == null) {
    438              outputs = new ArrayList<OutputConfiguration>();
    439          }
    440          if (outputs.size() == 0 && inputConfig != null) {
    441              throw new IllegalArgumentException("cannot configure an input stream without " +
    442                      "any output streams");
    443          }
    444  
    445          checkInputConfiguration(inputConfig);//拍照的inputConfig是NULL
    446  
    447          boolean success = false;
    448  
    449          synchronized(mInterfaceLock) {
    450              checkIfCameraClosedOrInError();
    451              // Streams to create
    452              HashSet<OutputConfiguration> addSet = new HashSet<OutputConfiguration>(outputs);
    453              // Streams to delete
    454              List<Integer> deleteList = new ArrayList<Integer>();
    455  
    456              // Determine which streams need to be created, which to be deleted
    457              for (int i = 0; i < mConfiguredOutputs.size(); ++i) {
    458                  int streamId = mConfiguredOutputs.keyAt(i);
    459                  OutputConfiguration outConfig = mConfiguredOutputs.valueAt(i);
    460  
    461                  if (!outputs.contains(outConfig) || outConfig.isDeferredConfiguration()) {
                             //把每次传递来的outputs和上次的mConfiguredOutputs对比,如果不一致就记录到删除的list中。
    462                      // Always delete the deferred output configuration when the session
    463                      // is created, as the deferred output configuration doesn't have unique surface
    464                      // related identifies.
    465                      deleteList.add(streamId);
    466                  } else {
    467                      addSet.remove(outConfig);  // Don't create a stream previously created
    468                  }
    469              }
    470  
    471              mDeviceExecutor.execute(mCallOnBusy);
    472              stopRepeating(); //停止预览
    473  
    474              try {
    475                  waitUntilIdle();
    476  
    477                  mRemoteDevice.beginConfigure(); //开始cinfigure
    478  
    479                  // reconfigure the input stream if the input configuration is different.
    480                  InputConfiguration currentInputConfig = mConfiguredInput.getValue();
    481                  if (inputConfig != currentInputConfig &&
    482                          (inputConfig == null || !inputConfig.equals(currentInputConfig))) {
    483                      if (currentInputConfig != null) {
    484                          mRemoteDevice.deleteStream(mConfiguredInput.getKey());
    485                          mConfiguredInput = new SimpleEntry<Integer, InputConfiguration>(
    486                                  REQUEST_ID_NONE, null);
    487                      }
    488                      if (inputConfig != null) {
    489                          int streamId = mRemoteDevice.createInputStream(inputConfig.getWidth(),
    490                                  inputConfig.getHeight(), inputConfig.getFormat(),
    491                                  inputConfig.isMultiResolution());
    492                          mConfiguredInput = new SimpleEntry<Integer, InputConfiguration>(
    493                                  streamId, inputConfig);
    494                      }
    495                  }
    496  
    497                  // Delete all streams first (to free up HW resources) 删掉streamID, 释放hw的资源
    498                  for (Integer streamId : deleteList) {
    499                      mRemoteDevice.deleteStream(streamId);
    500                      mConfiguredOutputs.delete(streamId);
    501                  }
    502  
    503                  // Add all new streams
    504                  for (OutputConfiguration outConfig : outputs) {
    505                      if (addSet.contains(outConfig)) {
                                 //app创建了几个surface,hal层就创建几个stream
    506                          int streamId = mRemoteDevice.createStream(outConfig);
                                 // 把streamId 和outputConfiguration缓存在mConfiguredOutputs中,以便和下次传递过来的output做比较。
    507                          mConfiguredOutputs.put(streamId, outConfig);
    508                      }
    509                  }
    510  
    511                  int offlineStreamIds[];//获取hal层的offlinestream id
    512                  if (sessionParams != null) {
    513                      offlineStreamIds = mRemoteDevice.endConfigure(operatingMode,
    514                              sessionParams.getNativeCopy(), createSessionStartTime); // 结束configure stream
    515                  } else {
    516                      offlineStreamIds = mRemoteDevice.endConfigure(operatingMode, null,
    517                              createSessionStartTime); 结束configure stream
    518                  }
    519  
    520                  mOfflineSupport.clear();
    521                  if ((offlineStreamIds != null) && (offlineStreamIds.length > 0)) {
    522                      for (int offlineStreamId : offlineStreamIds) {
    523                          mOfflineSupport.add(offlineStreamId);//把offlineStreamId存在mOfflineSupport HashSet中
    524                      }
    525                  }
    526  
    527                  success = true;
    528              } catch (IllegalArgumentException e) {
    529                  // OK. camera service can reject stream config if it's not supported by HAL
    530                  // This is only the result of a programmer misusing the camera2 api.
    531                  Log.w(TAG, "Stream configuration failed due to: " + e.getMessage());
    532                  return false;
    533              } catch (CameraAccessException e) {
    534                  if (e.getReason() == CameraAccessException.CAMERA_IN_USE) {
    535                      throw new IllegalStateException("The camera is currently busy." +
    536                              " You must wait until the previous operation completes.", e);
    537                  }
    538                  throw e;
    539              } finally {
    540                  if (success && outputs.size() > 0) {
    541                      mDeviceExecutor.execute(mCallOnIdle);
    542                  } else {
    543                      // Always return to the 'unconfigured' state if we didn't hit a fatal error
    544                      mDeviceExecutor.execute(mCallOnUnconfigured);
    545                  }
    546              }
    547          }
    548  
    549          return success;
    550      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122

    CameraDeviceImpl.java --> createStream 调用CameraDeviceClient.cpp 中的方法createStream

    859  binder::Status CameraDeviceClient::createStream(
    860          const hardware::camera2::params::OutputConfiguration &outputConfiguration,
    861          /*out*/
    862          int32_t* newStreamId) {
    863      ATRACE_CALL();
    864  
    865      binder::Status res;
    866      if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
    867  
    868      Mutex::Autolock icl(mBinderSerializationLock);
    869  
    870      const std::vector<sp<IGraphicBufferProducer>>& bufferProducers =
    871              outputConfiguration.getGraphicBufferProducers();//buffer生产者
    872      size_t numBufferProducers = bufferProducers.size();
    873      bool deferredConsumer = outputConfiguration.isDeferred();
    874      bool isShared = outputConfiguration.isShared();
    875      String8 physicalCameraId = String8(outputConfiguration.getPhysicalCameraId());
    876      bool deferredConsumerOnly = deferredConsumer && numBufferProducers == 0;
    877      bool isMultiResolution = outputConfiguration.isMultiResolution();
    878      int64_t dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
    879      int64_t streamUseCase = outputConfiguration.getStreamUseCase();
    880      int timestampBase = outputConfiguration.getTimestampBase();
    881      int mirrorMode = outputConfiguration.getMirrorMode();
    882  
    883      res = SessionConfigurationUtils::checkSurfaceType(numBufferProducers, deferredConsumer,
    884              outputConfiguration.getSurfaceType());
    885      if (!res.isOk()) {
    886          return res;
    887      }
    888  
    889      if (!mDevice.get()) {
    890          return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
    891      }
    892      res = SessionConfigurationUtils::checkPhysicalCameraId(mPhysicalCameraIds,
    893              physicalCameraId, mCameraIdStr);
    894      if (!res.isOk()) {
    895          return res;
    896      }
    897  
    898      std::vector<sp<Surface>> surfaces;
    899      std::vector<sp<IBinder>> binders;
    900      status_t err;
    901  
    902      // Create stream for deferred surface case.
    903      if (deferredConsumerOnly) {
    904          return createDeferredSurfaceStreamLocked(outputConfiguration, isShared, newStreamId);
    905      }
    906  
    907      OutputStreamInfo streamInfo;
    908      bool isStreamInfoValid = false;
    909      const std::vector<int32_t> &sensorPixelModesUsed =
    910              outputConfiguration.getSensorPixelModesUsed();
    911      for (auto& bufferProducer : bufferProducers) {
    912          // Don't create multiple streams for the same target surface
    913          sp<IBinder> binder = IInterface::asBinder(bufferProducer);
    914          ssize_t index = mStreamMap.indexOfKey(binder);
    915          if (index != NAME_NOT_FOUND) {
    916              String8 msg = String8::format("Camera %s: Surface already has a stream created for it "
    917                      "(ID %zd)", mCameraIdStr.string(), index);
    918              ALOGW("%s: %s", __FUNCTION__, msg.string());
    919              return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.string());
    920          }
    921  
    922          sp<Surface> surface;
    923          res = SessionConfigurationUtils::createSurfaceFromGbp(streamInfo,
    924                  isStreamInfoValid, surface, bufferProducer, mCameraIdStr,
    925                  mDevice->infoPhysical(physicalCameraId), sensorPixelModesUsed, dynamicRangeProfile,
    926                  streamUseCase, timestampBase, mirrorMode);
    927  
    928          if (!res.isOk())
    929              return res;
    930  
    931          if (!isStreamInfoValid) {
    932              isStreamInfoValid = true;
    933          }
    934  
    935          binders.push_back(IInterface::asBinder(bufferProducer));
    936          surfaces.push_back(surface);//生产者生产出来的对象放到集合中,等待消费者消费
    937      }
    938  
    939      // If mOverrideForPerfClass is true, do not fail createStream() for small
    940      // JPEG sizes because existing createSurfaceFromGbp() logic will find the
    941      // closest possible supported size.
    942  
    943      int streamId = camera3::CAMERA3_STREAM_ID_INVALID;
    944      std::vector<int> surfaceIds;
    945      bool isDepthCompositeStream =
    946              camera3::DepthCompositeStream::isDepthCompositeStream(surfaces[0]);
    947      bool isHeicCompisiteStream = camera3::HeicCompositeStream::isHeicCompositeStream(surfaces[0]);
    948      if (isDepthCompositeStream || isHeicCompisiteStream) {
    949          sp<CompositeStream> compositeStream;
    950          if (isDepthCompositeStream) {
    951              compositeStream = new camera3::DepthCompositeStream(mDevice, getRemoteCallback());
    952          } else {
    953              compositeStream = new camera3::HeicCompositeStream(mDevice, getRemoteCallback());
    954          }
    955  
    956          err = compositeStream->createStream(surfaces, deferredConsumer, streamInfo.width,
    957                  streamInfo.height, streamInfo.format,
    958                  static_cast<camera_stream_rotation_t>(outputConfiguration.getRotation()),
    959                  &streamId, physicalCameraId, streamInfo.sensorPixelModesUsed, &surfaceIds,
    960                  outputConfiguration.getSurfaceSetID(), isShared, isMultiResolution);
    961          if (err == OK) {
    962              Mutex::Autolock l(mCompositeLock);
    963              mCompositeStreamMap.add(IInterface::asBinder(surfaces[0]->getIGraphicBufferProducer()),
    964                      compositeStream);
    965          }
    966      } else {//streamInfo中信息比较多,database/format/width/height等等
    967          err = mDevice->createStream(surfaces, deferredConsumer, streamInfo.width,
    968                  streamInfo.height, streamInfo.format, streamInfo.dataSpace,
    969                  static_cast<camera_stream_rotation_t>(outputConfiguration.getRotation()),
    970                  &streamId, physicalCameraId, streamInfo.sensorPixelModesUsed, &surfaceIds,
    971                  outputConfiguration.getSurfaceSetID(), isShared, isMultiResolution,
    972                  /*consumerUsage*/0, streamInfo.dynamicRangeProfile, streamInfo.streamUseCase,
    973                  streamInfo.timestampBase, streamInfo.mirrorMode);
    974      }
    975  
    976      if (err != OK) {
    977          res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
    978                  "Camera %s: Error creating output stream (%d x %d, fmt %x, dataSpace %x): %s (%d)",
    979                  mCameraIdStr.string(), streamInfo.width, streamInfo.height, streamInfo.format,
    980                  streamInfo.dataSpace, strerror(-err), err);
    981      } else {
    982          int i = 0;
    983          for (auto& binder : binders) {
    984              ALOGV("%s: mStreamMap add binder %p streamId %d, surfaceId %d",
    985                      __FUNCTION__, binder.get(), streamId, i);
    986              mStreamMap.add(binder, StreamSurfaceId(streamId, surfaceIds[i]));
    987              i++;
    988          }
    989  
    990          mConfiguredOutputs.add(streamId, outputConfiguration);
    991          mStreamInfoMap[streamId] = streamInfo;
    992  
    993          ALOGV("%s: Camera %s: Successfully created a new stream ID %d for output surface"
    994                      " (%d x %d) with format 0x%x.",
    995                    __FUNCTION__, mCameraIdStr.string(), streamId, streamInfo.width,
    996                    streamInfo.height, streamInfo.format);
    997  
    998          // Set transform flags to ensure preview to be rotated correctly.
    999          res = setStreamTransformLocked(streamId, streamInfo.mirrorMode);
    1000  
    1001          // Fill in mHighResolutionCameraIdToStreamIdSet map
    1002          const String8 &cameraIdUsed =
    1003                  physicalCameraId.size() != 0 ? physicalCameraId : mCameraIdStr;
    1004          const char *cameraIdUsedCStr = cameraIdUsed.string();
    1005          // Only needed for high resolution sensors
    1006          if (mHighResolutionSensors.find(cameraIdUsedCStr) !=
    1007                  mHighResolutionSensors.end()) {
    1008              mHighResolutionCameraIdToStreamIdSet[cameraIdUsedCStr].insert(streamId);
    1009          }
    1010  
    1011          *newStreamId = streamId;
    1012      }
    1013  
    1014      return res;
    1015  }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157

    Camera3Device.cpp --> createStream

    982  status_t Camera3Device::createStream(sp<Surface> consumer,
    983              uint32_t width, uint32_t height, int format,
    984              android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
    985              const String8& physicalCameraId,
    986              const std::unordered_set<int32_t> &sensorPixelModesUsed,
    987              std::vector<int> *surfaceIds, int streamSetId, bool isShared, bool isMultiResolution,
    988              uint64_t consumerUsage, int64_t dynamicRangeProfile, int64_t streamUseCase,
    989              int timestampBase, int mirrorMode) {
    990      ATRACE_CALL();
    991  
    992      if (consumer == nullptr) {
    993          ALOGE("%s: consumer must not be null", __FUNCTION__);
    994          return BAD_VALUE;
    995      }
    996  
    997      std::vector<sp<Surface>> consumers; //消费者,surface是生产者消费者模式
    998      consumers.push_back(consumer);
    999  
    1000      return createStream(consumers, /*hasDeferredConsumer*/ false, width, height,
    1001              format, dataSpace, rotation, id, physicalCameraId, sensorPixelModesUsed, surfaceIds,
    1002              streamSetId, isShared, isMultiResolution, consumerUsage, dynamicRangeProfile,
    1003              streamUseCase, timestampBase, mirrorMode);
    1004  }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    configureStreamsLocked --> mInterface->configureStreams
    调用到这里就调用到hal的configureStreams的方法中去了。

    2411      // Do the HAL configuration; will potentially touch stream
    2412      // max_buffers, usage, and priv fields, as well as data_space and format
    2413      // fields for IMPLEMENTATION_DEFINED formats.
    2414  
    2415      const camera_metadata_t *sessionBuffer = sessionParams.getAndLock();
    2416      res = mInterface->configureStreams(sessionBuffer, &config, bufferSizes);
    2417      sessionParams.unlock(sessionBuffer);
    2418  
    2419      if (res == BAD_VALUE) {
    2420          // HAL rejected this set of streams as unsupported, clean up config
    2421          // attempt and return to unconfigured state
    2422          CLOGE("Set of requested inputs/outputs not supported by HAL");
    2423          cancelStreamsConfigurationLocked();
    2424          return BAD_VALUE;
    2425      } else if (res != OK) {
    2426          // Some other kind of error from configure_streams - this is not
    2427          // expected
    2428          SET_ERR_L("Unable to configure streams with HAL: %s (%d)",
    2429                  strerror(-res), res);
    2430          return res;
    2431      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  • 相关阅读:
    Android 常用布局介绍
    C Primer Plus(6) 中文版 第6章 C控制语句:循环 6.11 数组简介
    01 概率论的基本概念
    摊牌了,请各位做好一年内随时失业的准备
    ShardingSphere-proxy-5.0.0分布式哈希取模分片实现(四)
    多方位解析 C 端、B 端产品特性
    UML/SysML建模工具更新情况-截至2024年4月(1)5款-Trufun建模平台 v2024
    【SSL 1589】汉明距离(NTT)
    vs2017编译的64位libssh2库
    TS代码整洁之道(下)
  • 原文地址:https://blog.csdn.net/wdaming1986/article/details/134303413