Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 94c1c2a5 authored by Ján Sebechlebský's avatar Ján Sebechlebský Committed by Android (Google) Code Review
Browse files

Merge "Fail if there's problem with tmp buffer during JPEG capture" into main

parents 5de51fc8 5c789e42
Loading
Loading
Loading
Loading
+26 −27
Original line number Original line Diff line number Diff line
@@ -581,8 +581,14 @@ ndk::ScopedAStatus VirtualCameraRenderThread::renderIntoBlobStreamBuffer(
  std::shared_ptr<AHardwareBuffer> inHwBuffer = framebuffer->getHardwareBuffer();
  std::shared_ptr<AHardwareBuffer> inHwBuffer = framebuffer->getHardwareBuffer();
  GraphicBuffer* gBuffer = GraphicBuffer::fromAHardwareBuffer(inHwBuffer.get());
  GraphicBuffer* gBuffer = GraphicBuffer::fromAHardwareBuffer(inHwBuffer.get());


  std::optional<size_t> compressedSize;
  if (gBuffer == nullptr) {
  if (gBuffer != nullptr) {
    ALOGE(
        "%s: Encountered invalid temporary buffer while rendering JPEG "
        "into BLOB stream",
        __func__);
    return cameraStatus(Status::INTERNAL_ERROR);
  }

  if (gBuffer->getPixelFormat() != HAL_PIXEL_FORMAT_YCbCr_420_888) {
  if (gBuffer->getPixelFormat() != HAL_PIXEL_FORMAT_YCbCr_420_888) {
    // This should never happen since we're allocating the temporary buffer
    // This should never happen since we're allocating the temporary buffer
    // with YUV420 layout above.
    // with YUV420 layout above.
@@ -600,17 +606,10 @@ ndk::ScopedAStatus VirtualCameraRenderThread::renderIntoBlobStreamBuffer(
      createExif(Resolution(stream->width, stream->height),
      createExif(Resolution(stream->width, stream->height),
                 createThumbnail(requestSettings.thumbnailResolution,
                 createThumbnail(requestSettings.thumbnailResolution,
                                 requestSettings.thumbnailJpegQuality));
                                 requestSettings.thumbnailJpegQuality));
    compressedSize = compressJpeg(
  std::optional<size_t> compressedSize = compressJpeg(
      gBuffer->getWidth(), gBuffer->getHeight(), requestSettings.jpegQuality,
      gBuffer->getWidth(), gBuffer->getHeight(), requestSettings.jpegQuality,
      *yCbCrLock, app1ExifData, stream->bufferSize - sizeof(CameraBlob),
      *yCbCrLock, app1ExifData, stream->bufferSize - sizeof(CameraBlob),
      (*planesLock).planes[0].data);
      (*planesLock).planes[0].data);
  } else {
    std::vector<uint8_t> app1ExifData =
        createExif(Resolution(stream->width, stream->height));
    compressedSize = compressBlackJpeg(
        stream->width, stream->height, requestSettings.jpegQuality, app1ExifData,
        stream->bufferSize - sizeof(CameraBlob), (*planesLock).planes[0].data);
  }


  if (!compressedSize.has_value()) {
  if (!compressedSize.has_value()) {
    ALOGE("%s: Failed to compress JPEG image", __func__);
    ALOGE("%s: Failed to compress JPEG image", __func__);
+0 −23
Original line number Original line Diff line number Diff line
@@ -153,18 +153,6 @@ class LibJpegContext {
    return compress(yLines, cbLines, crLines);
    return compress(yLines, cbLines, crLines);
  }
  }


  std::optional<size_t> compressBlackImage() {
    // We only really need to prepare one scanline for Y and one shared scanline
    // for Cb & Cr.
    std::vector<uint8_t> yLine(mWidth, 0);
    std::vector<uint8_t> chromaLine(mWidth / 2, 0xff / 2);

    std::vector<JSAMPROW> yLines(mHeight, yLine.data());
    std::vector<JSAMPROW> cLines(mHeight / 2, chromaLine.data());

    return compress(yLines, cLines, cLines);
  }

 private:
 private:
  void setSuccess(const boolean success) {
  void setSuccess(const boolean success) {
    mSuccess = success;
    mSuccess = success;
@@ -279,17 +267,6 @@ std::optional<size_t> compressJpeg(const int width, const int height,
  return context.compress(ycbcr);
  return context.compress(ycbcr);
}
}


std::optional<size_t> compressBlackJpeg(const int width, const int height,
                                        const int quality,
                                        const std::vector<uint8_t>& app1ExifData,
                                        size_t outBufferSize, void* outBuffer) {
  LibJpegContext context(width, height, quality, outBufferSize, outBuffer);
  if (!app1ExifData.empty()) {
    context.setApp1Data(app1ExifData.data(), app1ExifData.size());
  }
  return context.compressBlackImage();
}

}  // namespace virtualcamera
}  // namespace virtualcamera
}  // namespace companion
}  // namespace companion
}  // namespace android
}  // namespace android
+0 −16
Original line number Original line Diff line number Diff line
@@ -17,10 +17,8 @@
#ifndef ANDROID_COMPANION_VIRTUALCAMERA_JPEGUTIL_H
#ifndef ANDROID_COMPANION_VIRTUALCAMERA_JPEGUTIL_H
#define ANDROID_COMPANION_VIRTUALCAMERA_JPEGUTIL_H
#define ANDROID_COMPANION_VIRTUALCAMERA_JPEGUTIL_H


#include <memory>
#include <optional>
#include <optional>


#include "android/hardware_buffer.h"
#include "system/graphics.h"
#include "system/graphics.h"


namespace android {
namespace android {
@@ -43,20 +41,6 @@ std::optional<size_t> compressJpeg(int width, int height, int quality,
                                   const std::vector<uint8_t>& app1ExifData,
                                   const std::vector<uint8_t>& app1ExifData,
                                   size_t outBufferSize, void* outBuffer);
                                   size_t outBufferSize, void* outBuffer);


// Jpeg-compress all-black image into the output buffer.
// * width - width of the image
// * heigh - height of the image
// * quality - 0-100, higher number corresponds to higher quality.
// * app1ExifData - vector containing data to be included in APP1
//   segment. Can be empty.
// * outBufferSize - capacity of the output buffer.
// * outBuffer - output buffer to write compressed data into.
// Returns size of compressed data if the compression was successful,
// empty optional otherwise.
std::optional<size_t> compressBlackJpeg(int width, int height, int quality,
                                        const std::vector<uint8_t>& app1ExifData,
                                        size_t outBufferSize, void* outBuffer);

}  // namespace virtualcamera
}  // namespace virtualcamera
}  // namespace companion
}  // namespace companion
}  // namespace android
}  // namespace android