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

Commit 7d6c4035 authored by Emilian Peev's avatar Emilian Peev
Browse files

Camera: Check for minimum depth Jpeg output size

The Jpeg encoder assumes a miminum output buffer size
which should at least be sufficient for the headers.
In worst case scenario, the Jpeg buffer can be overwritten
before the library detects and flags the error.
Check the depth Jpeg output buffer size before trying
to encode the final image and re-use the minimum value
as defined in the Camera3Device.

FLAG: EXEMPT bugfix
Bug: 358210775
Test: atest frameworks/av/services/camera/libcameraservice/tests/DepthProcessorTest.cpp
Change-Id: I93021e87681864da76f447017dda00981661f9f0
parent 2bc40685
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -417,7 +417,8 @@ std::unique_ptr<dynamic_depth::DepthMap> processDepthMapFrame(DepthPhotoInputFra
int processDepthPhotoFrame(DepthPhotoInputFrame inputFrame, size_t depthPhotoBufferSize,
        void* depthPhotoBuffer /*out*/, size_t* depthPhotoActualSize /*out*/) {
    if ((inputFrame.mMainJpegBuffer == nullptr) || (inputFrame.mDepthMapBuffer == nullptr) ||
            (depthPhotoBuffer == nullptr) || (depthPhotoActualSize == nullptr)) {
            (depthPhotoBuffer == nullptr) || (depthPhotoActualSize == nullptr) ||
            (inputFrame.mMaxJpegSize < MIN_JPEG_BUFFER_SIZE)) {
        return BAD_VALUE;
    }

+3 −0
Original line number Diff line number Diff line
@@ -23,6 +23,9 @@
namespace android {
namespace camera3 {

// minimal jpeg buffer size: 256KB. Blob header is not included.
constexpr const size_t MIN_JPEG_BUFFER_SIZE = 256 * 1024;

enum DepthPhotoOrientation {
    DEPTH_ORIENTATION_0_DEGREES   = 0,
    DEPTH_ORIENTATION_90_DEGREES  = 90,
+3 −2
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#include <aidl/android/hardware/camera/device/CameraBlob.h>

#include "common/CameraDeviceBase.h"
#include "common/DepthPhotoProcessor.h"
#include "device3/BufferUtils.h"
#include "device3/StatusTracker.h"
#include "device3/Camera3BufferManager.h"
@@ -376,8 +377,8 @@ class Camera3Device :

    struct                     RequestTrigger;
    // minimal jpeg buffer size: 256KB + blob header
    static const ssize_t       kMinJpegBufferSize =
            256 * 1024 + sizeof(aidl::android::hardware::camera::device::CameraBlob);
    static const ssize_t       kMinJpegBufferSize = camera3::MIN_JPEG_BUFFER_SIZE +
            sizeof(aidl::android::hardware::camera::device::CameraBlob);
    // Constant to use for stream ID when one doesn't exist
    static const int           NO_STREAM = -1;

+12 −9
Original line number Diff line number Diff line
@@ -78,30 +78,30 @@ void generateDepth16Buffer(std::array<uint16_t, kTestBufferDepthSize> *depth16Bu
}

TEST(DepthProcessorTest, BadInput) {
    static const size_t badInputBufferWidth = 17;
    static const size_t badInputBufferHeight = 3;
    static const size_t badInputJpegSize = 63;
    static const size_t badInputBufferDepthSize = (badInputBufferWidth * badInputBufferHeight);
    int jpegQuality = 95;

    DepthPhotoInputFrame inputFrame;
    std::vector<uint8_t> colorJpegBuffer(badInputJpegSize);
    inputFrame.mMainJpegSize = colorJpegBuffer.size();
    // Worst case both depth and confidence maps have the same size as the main color image.
    inputFrame.mMaxJpegSize = inputFrame.mMainJpegSize * 3;

    std::vector<uint8_t> colorJpegBuffer;
    generateColorJpegBuffer(jpegQuality, ExifOrientation::ORIENTATION_UNDEFINED,
            /*includeExif*/ false, /*switchDimensions*/ false, &colorJpegBuffer);

    std::array<uint16_t, kTestBufferDepthSize> depth16Buffer;
    generateDepth16Buffer(&depth16Buffer);
    std::array<uint16_t, badInputBufferDepthSize> depth16Buffer;

    std::vector<uint8_t> depthPhotoBuffer(inputFrame.mMaxJpegSize);
    size_t actualDepthPhotoSize = 0;

    inputFrame.mMainJpegWidth = kTestBufferWidth;
    inputFrame.mMainJpegHeight = kTestBufferHeight;
    inputFrame.mMainJpegWidth = badInputBufferWidth;
    inputFrame.mMainJpegHeight = badInputBufferHeight;
    inputFrame.mJpegQuality = jpegQuality;
    ASSERT_NE(processDepthPhotoFrame(inputFrame, depthPhotoBuffer.size(), depthPhotoBuffer.data(),
                &actualDepthPhotoSize), 0);

    inputFrame.mMainJpegBuffer = reinterpret_cast<const char*> (colorJpegBuffer.data());
    inputFrame.mMainJpegSize = colorJpegBuffer.size();
    ASSERT_NE(processDepthPhotoFrame(inputFrame, depthPhotoBuffer.size(), depthPhotoBuffer.data(),
                &actualDepthPhotoSize), 0);

@@ -113,6 +113,9 @@ TEST(DepthProcessorTest, BadInput) {

    ASSERT_NE(processDepthPhotoFrame(inputFrame, depthPhotoBuffer.size(), depthPhotoBuffer.data(),
                nullptr), 0);

    ASSERT_NE(processDepthPhotoFrame(inputFrame, depthPhotoBuffer.size(), depthPhotoBuffer.data(),
                &actualDepthPhotoSize), 0);
}

TEST(DepthProcessorTest, BasicDepthPhotoValidation) {