Android camera2 api. Setting multiple ImageReader surfaces gives blank output












2















I have a camera2 implementation. The current setup is, it uses a texture view surface to display the actual camera view and an ImageReader surface for capturing images.



Now I want to capture preview frames as well. So I tried adding a new ImageReader surface for capturing frames. But when I add that surface to createCaptureSession request, the screen goes blank. What could possibly be wrong? Below is the code that I use to add surfaces to createCaptureSession



val surface = preview.surface
?: throw CameraAccessException(CameraAccessException.CAMERA_ERROR)

val previewIRSurface = previewImageReader?.surface
?: throw CameraAccessException(CameraAccessException.CAMERA_ERROR)

val captureSurface = captureImageReader?.surface
?: throw CameraAccessException(CameraAccessException.CAMERA_ERROR)

try {
val template = if (zsl) CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG else CameraDevice.TEMPLATE_PREVIEW

previewRequestBuilder = camera?.createCaptureRequest(template)
?.apply { addTarget(surface) }
?: throw CameraAccessException(CameraAccessException.CAMERA_ERROR)

val surfaces: ArrayList<Surface> = arrayListOf(surface, previewIRSurface, captureSurface)

camera?.createCaptureSession(surfaces, sessionCallback, backgroundHandler)

} catch (e: CameraAccessException) {
throw RuntimeException("Failed to start camera session")
}


The initialization of ImageReaders is like this.



private fun prepareImageReaders() {

val largestPreview = previewSizes.sizes(aspectRatio).last()

previewImageReader?.close()

previewImageReader = ImageReader.newInstance(
largestPreview.width,
largestPreview.height,
internalOutputFormat,
4 // maxImages
).apply { setOnImageAvailableListener(onPreviewImageAvailableListener, backgroundHandler) }

val largestPicture = pictureSizes.sizes(aspectRatio).last()

captureImageReader?.close()

captureImageReader = ImageReader.newInstance(
largestPicture.width,
largestPicture.height,
internalOutputFormat,
2 // maxImages
).apply { setOnImageAvailableListener(onCaptureImageAvailableListener, backgroundHandler) }
}


More clarifications about the parameters used above:





  • internalOutput format is either ImageFormat.JPEG or ImageFormat.YUV_420_888.

  • Image sizes are based on best possible sizes

  • It works good with either of the image readers individually but as soon as I add both together, blank screen!

  • Testing on Samsung Galaxy S8 with Android Oreo (8.0)


The original code is here https://github.com/pvasa/cameraview-ex/blob/development/cameraViewEx/src/main/api21/com/priyankvasa/android/cameraviewex/Camera2.kt










share|improve this question





























    2















    I have a camera2 implementation. The current setup is, it uses a texture view surface to display the actual camera view and an ImageReader surface for capturing images.



    Now I want to capture preview frames as well. So I tried adding a new ImageReader surface for capturing frames. But when I add that surface to createCaptureSession request, the screen goes blank. What could possibly be wrong? Below is the code that I use to add surfaces to createCaptureSession



    val surface = preview.surface
    ?: throw CameraAccessException(CameraAccessException.CAMERA_ERROR)

    val previewIRSurface = previewImageReader?.surface
    ?: throw CameraAccessException(CameraAccessException.CAMERA_ERROR)

    val captureSurface = captureImageReader?.surface
    ?: throw CameraAccessException(CameraAccessException.CAMERA_ERROR)

    try {
    val template = if (zsl) CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG else CameraDevice.TEMPLATE_PREVIEW

    previewRequestBuilder = camera?.createCaptureRequest(template)
    ?.apply { addTarget(surface) }
    ?: throw CameraAccessException(CameraAccessException.CAMERA_ERROR)

    val surfaces: ArrayList<Surface> = arrayListOf(surface, previewIRSurface, captureSurface)

    camera?.createCaptureSession(surfaces, sessionCallback, backgroundHandler)

    } catch (e: CameraAccessException) {
    throw RuntimeException("Failed to start camera session")
    }


    The initialization of ImageReaders is like this.



    private fun prepareImageReaders() {

    val largestPreview = previewSizes.sizes(aspectRatio).last()

    previewImageReader?.close()

    previewImageReader = ImageReader.newInstance(
    largestPreview.width,
    largestPreview.height,
    internalOutputFormat,
    4 // maxImages
    ).apply { setOnImageAvailableListener(onPreviewImageAvailableListener, backgroundHandler) }

    val largestPicture = pictureSizes.sizes(aspectRatio).last()

    captureImageReader?.close()

    captureImageReader = ImageReader.newInstance(
    largestPicture.width,
    largestPicture.height,
    internalOutputFormat,
    2 // maxImages
    ).apply { setOnImageAvailableListener(onCaptureImageAvailableListener, backgroundHandler) }
    }


    More clarifications about the parameters used above:





    • internalOutput format is either ImageFormat.JPEG or ImageFormat.YUV_420_888.

    • Image sizes are based on best possible sizes

    • It works good with either of the image readers individually but as soon as I add both together, blank screen!

    • Testing on Samsung Galaxy S8 with Android Oreo (8.0)


    The original code is here https://github.com/pvasa/cameraview-ex/blob/development/cameraViewEx/src/main/api21/com/priyankvasa/android/cameraviewex/Camera2.kt










    share|improve this question



























      2












      2








      2








      I have a camera2 implementation. The current setup is, it uses a texture view surface to display the actual camera view and an ImageReader surface for capturing images.



      Now I want to capture preview frames as well. So I tried adding a new ImageReader surface for capturing frames. But when I add that surface to createCaptureSession request, the screen goes blank. What could possibly be wrong? Below is the code that I use to add surfaces to createCaptureSession



      val surface = preview.surface
      ?: throw CameraAccessException(CameraAccessException.CAMERA_ERROR)

      val previewIRSurface = previewImageReader?.surface
      ?: throw CameraAccessException(CameraAccessException.CAMERA_ERROR)

      val captureSurface = captureImageReader?.surface
      ?: throw CameraAccessException(CameraAccessException.CAMERA_ERROR)

      try {
      val template = if (zsl) CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG else CameraDevice.TEMPLATE_PREVIEW

      previewRequestBuilder = camera?.createCaptureRequest(template)
      ?.apply { addTarget(surface) }
      ?: throw CameraAccessException(CameraAccessException.CAMERA_ERROR)

      val surfaces: ArrayList<Surface> = arrayListOf(surface, previewIRSurface, captureSurface)

      camera?.createCaptureSession(surfaces, sessionCallback, backgroundHandler)

      } catch (e: CameraAccessException) {
      throw RuntimeException("Failed to start camera session")
      }


      The initialization of ImageReaders is like this.



      private fun prepareImageReaders() {

      val largestPreview = previewSizes.sizes(aspectRatio).last()

      previewImageReader?.close()

      previewImageReader = ImageReader.newInstance(
      largestPreview.width,
      largestPreview.height,
      internalOutputFormat,
      4 // maxImages
      ).apply { setOnImageAvailableListener(onPreviewImageAvailableListener, backgroundHandler) }

      val largestPicture = pictureSizes.sizes(aspectRatio).last()

      captureImageReader?.close()

      captureImageReader = ImageReader.newInstance(
      largestPicture.width,
      largestPicture.height,
      internalOutputFormat,
      2 // maxImages
      ).apply { setOnImageAvailableListener(onCaptureImageAvailableListener, backgroundHandler) }
      }


      More clarifications about the parameters used above:





      • internalOutput format is either ImageFormat.JPEG or ImageFormat.YUV_420_888.

      • Image sizes are based on best possible sizes

      • It works good with either of the image readers individually but as soon as I add both together, blank screen!

      • Testing on Samsung Galaxy S8 with Android Oreo (8.0)


      The original code is here https://github.com/pvasa/cameraview-ex/blob/development/cameraViewEx/src/main/api21/com/priyankvasa/android/cameraviewex/Camera2.kt










      share|improve this question
















      I have a camera2 implementation. The current setup is, it uses a texture view surface to display the actual camera view and an ImageReader surface for capturing images.



      Now I want to capture preview frames as well. So I tried adding a new ImageReader surface for capturing frames. But when I add that surface to createCaptureSession request, the screen goes blank. What could possibly be wrong? Below is the code that I use to add surfaces to createCaptureSession



      val surface = preview.surface
      ?: throw CameraAccessException(CameraAccessException.CAMERA_ERROR)

      val previewIRSurface = previewImageReader?.surface
      ?: throw CameraAccessException(CameraAccessException.CAMERA_ERROR)

      val captureSurface = captureImageReader?.surface
      ?: throw CameraAccessException(CameraAccessException.CAMERA_ERROR)

      try {
      val template = if (zsl) CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG else CameraDevice.TEMPLATE_PREVIEW

      previewRequestBuilder = camera?.createCaptureRequest(template)
      ?.apply { addTarget(surface) }
      ?: throw CameraAccessException(CameraAccessException.CAMERA_ERROR)

      val surfaces: ArrayList<Surface> = arrayListOf(surface, previewIRSurface, captureSurface)

      camera?.createCaptureSession(surfaces, sessionCallback, backgroundHandler)

      } catch (e: CameraAccessException) {
      throw RuntimeException("Failed to start camera session")
      }


      The initialization of ImageReaders is like this.



      private fun prepareImageReaders() {

      val largestPreview = previewSizes.sizes(aspectRatio).last()

      previewImageReader?.close()

      previewImageReader = ImageReader.newInstance(
      largestPreview.width,
      largestPreview.height,
      internalOutputFormat,
      4 // maxImages
      ).apply { setOnImageAvailableListener(onPreviewImageAvailableListener, backgroundHandler) }

      val largestPicture = pictureSizes.sizes(aspectRatio).last()

      captureImageReader?.close()

      captureImageReader = ImageReader.newInstance(
      largestPicture.width,
      largestPicture.height,
      internalOutputFormat,
      2 // maxImages
      ).apply { setOnImageAvailableListener(onCaptureImageAvailableListener, backgroundHandler) }
      }


      More clarifications about the parameters used above:





      • internalOutput format is either ImageFormat.JPEG or ImageFormat.YUV_420_888.

      • Image sizes are based on best possible sizes

      • It works good with either of the image readers individually but as soon as I add both together, blank screen!

      • Testing on Samsung Galaxy S8 with Android Oreo (8.0)


      The original code is here https://github.com/pvasa/cameraview-ex/blob/development/cameraViewEx/src/main/api21/com/priyankvasa/android/cameraviewex/Camera2.kt







      android kotlin android-camera2






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 14 '18 at 23:21







      priyank

















      asked Nov 14 '18 at 20:37









      priyankpriyank

      1,97341530




      1,97341530
























          1 Answer
          1






          active

          oldest

          votes


















          1














          maxImages == 4 may be too much and exhaust your RAM. Also, it's not clear what internalOutputFormat you use, and whether it is compatible with the largestPreview size.



          The bottom line is, study the long list of tables for supported surface list parameter of createCaptureSession(). Depending on your camera capabilities, the three surfaces that you use, could be too much.






          share|improve this answer
























          • Thanks for the quick response Alex. I will add clarifications about all of that in the original post. The internalOutputFormat is ImageFormat.JPEG, I also tried with ImageFormat.YUV_420_888 but same result. Also maxImages = 4 is safe in this case because I only request next frame once I am done with current one. Both the image readers work individually if I don't use the other one. But together it is just blank screen. I wonder if the device is relevant. If so I am testing on Samsung Galaxy S8 with Android 8.0

            – priyank
            Nov 14 '18 at 23:09








          • 2





            As Alex says, there are limits to how many simultaneous outputs you can add to a capture session. There should be errors in either the session creation or when submitting the first capture request, so try checking if any capture errors are being reported to your app. Or if the capture session creation is returning an error callback.

            – Eddy Talvala
            Nov 14 '18 at 23:31











          • @EddyTalvala thanks for pointing me to exceptions. The error itself doesn't say much Stream configuration failed due to: endConfigure:434 but upon searching, it is found that multiple surfaces are not supported for JPEG format. Upon changing it to YUV_420_888 it works flawlessly.

            – priyank
            Nov 15 '18 at 0:02











          • Yes, jpeg is the king of image formats. I mean, there may be only one jpeg in capture session, or none.

            – Alex Cohn
            Nov 15 '18 at 6:02













          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53308362%2fandroid-camera2-api-setting-multiple-imagereader-surfaces-gives-blank-output%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          maxImages == 4 may be too much and exhaust your RAM. Also, it's not clear what internalOutputFormat you use, and whether it is compatible with the largestPreview size.



          The bottom line is, study the long list of tables for supported surface list parameter of createCaptureSession(). Depending on your camera capabilities, the three surfaces that you use, could be too much.






          share|improve this answer
























          • Thanks for the quick response Alex. I will add clarifications about all of that in the original post. The internalOutputFormat is ImageFormat.JPEG, I also tried with ImageFormat.YUV_420_888 but same result. Also maxImages = 4 is safe in this case because I only request next frame once I am done with current one. Both the image readers work individually if I don't use the other one. But together it is just blank screen. I wonder if the device is relevant. If so I am testing on Samsung Galaxy S8 with Android 8.0

            – priyank
            Nov 14 '18 at 23:09








          • 2





            As Alex says, there are limits to how many simultaneous outputs you can add to a capture session. There should be errors in either the session creation or when submitting the first capture request, so try checking if any capture errors are being reported to your app. Or if the capture session creation is returning an error callback.

            – Eddy Talvala
            Nov 14 '18 at 23:31











          • @EddyTalvala thanks for pointing me to exceptions. The error itself doesn't say much Stream configuration failed due to: endConfigure:434 but upon searching, it is found that multiple surfaces are not supported for JPEG format. Upon changing it to YUV_420_888 it works flawlessly.

            – priyank
            Nov 15 '18 at 0:02











          • Yes, jpeg is the king of image formats. I mean, there may be only one jpeg in capture session, or none.

            – Alex Cohn
            Nov 15 '18 at 6:02


















          1














          maxImages == 4 may be too much and exhaust your RAM. Also, it's not clear what internalOutputFormat you use, and whether it is compatible with the largestPreview size.



          The bottom line is, study the long list of tables for supported surface list parameter of createCaptureSession(). Depending on your camera capabilities, the three surfaces that you use, could be too much.






          share|improve this answer
























          • Thanks for the quick response Alex. I will add clarifications about all of that in the original post. The internalOutputFormat is ImageFormat.JPEG, I also tried with ImageFormat.YUV_420_888 but same result. Also maxImages = 4 is safe in this case because I only request next frame once I am done with current one. Both the image readers work individually if I don't use the other one. But together it is just blank screen. I wonder if the device is relevant. If so I am testing on Samsung Galaxy S8 with Android 8.0

            – priyank
            Nov 14 '18 at 23:09








          • 2





            As Alex says, there are limits to how many simultaneous outputs you can add to a capture session. There should be errors in either the session creation or when submitting the first capture request, so try checking if any capture errors are being reported to your app. Or if the capture session creation is returning an error callback.

            – Eddy Talvala
            Nov 14 '18 at 23:31











          • @EddyTalvala thanks for pointing me to exceptions. The error itself doesn't say much Stream configuration failed due to: endConfigure:434 but upon searching, it is found that multiple surfaces are not supported for JPEG format. Upon changing it to YUV_420_888 it works flawlessly.

            – priyank
            Nov 15 '18 at 0:02











          • Yes, jpeg is the king of image formats. I mean, there may be only one jpeg in capture session, or none.

            – Alex Cohn
            Nov 15 '18 at 6:02
















          1












          1








          1







          maxImages == 4 may be too much and exhaust your RAM. Also, it's not clear what internalOutputFormat you use, and whether it is compatible with the largestPreview size.



          The bottom line is, study the long list of tables for supported surface list parameter of createCaptureSession(). Depending on your camera capabilities, the three surfaces that you use, could be too much.






          share|improve this answer













          maxImages == 4 may be too much and exhaust your RAM. Also, it's not clear what internalOutputFormat you use, and whether it is compatible with the largestPreview size.



          The bottom line is, study the long list of tables for supported surface list parameter of createCaptureSession(). Depending on your camera capabilities, the three surfaces that you use, could be too much.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 14 '18 at 23:05









          Alex CohnAlex Cohn

          41.6k553190




          41.6k553190













          • Thanks for the quick response Alex. I will add clarifications about all of that in the original post. The internalOutputFormat is ImageFormat.JPEG, I also tried with ImageFormat.YUV_420_888 but same result. Also maxImages = 4 is safe in this case because I only request next frame once I am done with current one. Both the image readers work individually if I don't use the other one. But together it is just blank screen. I wonder if the device is relevant. If so I am testing on Samsung Galaxy S8 with Android 8.0

            – priyank
            Nov 14 '18 at 23:09








          • 2





            As Alex says, there are limits to how many simultaneous outputs you can add to a capture session. There should be errors in either the session creation or when submitting the first capture request, so try checking if any capture errors are being reported to your app. Or if the capture session creation is returning an error callback.

            – Eddy Talvala
            Nov 14 '18 at 23:31











          • @EddyTalvala thanks for pointing me to exceptions. The error itself doesn't say much Stream configuration failed due to: endConfigure:434 but upon searching, it is found that multiple surfaces are not supported for JPEG format. Upon changing it to YUV_420_888 it works flawlessly.

            – priyank
            Nov 15 '18 at 0:02











          • Yes, jpeg is the king of image formats. I mean, there may be only one jpeg in capture session, or none.

            – Alex Cohn
            Nov 15 '18 at 6:02





















          • Thanks for the quick response Alex. I will add clarifications about all of that in the original post. The internalOutputFormat is ImageFormat.JPEG, I also tried with ImageFormat.YUV_420_888 but same result. Also maxImages = 4 is safe in this case because I only request next frame once I am done with current one. Both the image readers work individually if I don't use the other one. But together it is just blank screen. I wonder if the device is relevant. If so I am testing on Samsung Galaxy S8 with Android 8.0

            – priyank
            Nov 14 '18 at 23:09








          • 2





            As Alex says, there are limits to how many simultaneous outputs you can add to a capture session. There should be errors in either the session creation or when submitting the first capture request, so try checking if any capture errors are being reported to your app. Or if the capture session creation is returning an error callback.

            – Eddy Talvala
            Nov 14 '18 at 23:31











          • @EddyTalvala thanks for pointing me to exceptions. The error itself doesn't say much Stream configuration failed due to: endConfigure:434 but upon searching, it is found that multiple surfaces are not supported for JPEG format. Upon changing it to YUV_420_888 it works flawlessly.

            – priyank
            Nov 15 '18 at 0:02











          • Yes, jpeg is the king of image formats. I mean, there may be only one jpeg in capture session, or none.

            – Alex Cohn
            Nov 15 '18 at 6:02



















          Thanks for the quick response Alex. I will add clarifications about all of that in the original post. The internalOutputFormat is ImageFormat.JPEG, I also tried with ImageFormat.YUV_420_888 but same result. Also maxImages = 4 is safe in this case because I only request next frame once I am done with current one. Both the image readers work individually if I don't use the other one. But together it is just blank screen. I wonder if the device is relevant. If so I am testing on Samsung Galaxy S8 with Android 8.0

          – priyank
          Nov 14 '18 at 23:09







          Thanks for the quick response Alex. I will add clarifications about all of that in the original post. The internalOutputFormat is ImageFormat.JPEG, I also tried with ImageFormat.YUV_420_888 but same result. Also maxImages = 4 is safe in this case because I only request next frame once I am done with current one. Both the image readers work individually if I don't use the other one. But together it is just blank screen. I wonder if the device is relevant. If so I am testing on Samsung Galaxy S8 with Android 8.0

          – priyank
          Nov 14 '18 at 23:09






          2




          2





          As Alex says, there are limits to how many simultaneous outputs you can add to a capture session. There should be errors in either the session creation or when submitting the first capture request, so try checking if any capture errors are being reported to your app. Or if the capture session creation is returning an error callback.

          – Eddy Talvala
          Nov 14 '18 at 23:31





          As Alex says, there are limits to how many simultaneous outputs you can add to a capture session. There should be errors in either the session creation or when submitting the first capture request, so try checking if any capture errors are being reported to your app. Or if the capture session creation is returning an error callback.

          – Eddy Talvala
          Nov 14 '18 at 23:31













          @EddyTalvala thanks for pointing me to exceptions. The error itself doesn't say much Stream configuration failed due to: endConfigure:434 but upon searching, it is found that multiple surfaces are not supported for JPEG format. Upon changing it to YUV_420_888 it works flawlessly.

          – priyank
          Nov 15 '18 at 0:02





          @EddyTalvala thanks for pointing me to exceptions. The error itself doesn't say much Stream configuration failed due to: endConfigure:434 but upon searching, it is found that multiple surfaces are not supported for JPEG format. Upon changing it to YUV_420_888 it works flawlessly.

          – priyank
          Nov 15 '18 at 0:02













          Yes, jpeg is the king of image formats. I mean, there may be only one jpeg in capture session, or none.

          – Alex Cohn
          Nov 15 '18 at 6:02







          Yes, jpeg is the king of image formats. I mean, there may be only one jpeg in capture session, or none.

          – Alex Cohn
          Nov 15 '18 at 6:02






















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53308362%2fandroid-camera2-api-setting-multiple-imagereader-surfaces-gives-blank-output%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Florida Star v. B. J. F.

          Danny Elfman

          Lugert, Oklahoma