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

Commit a4a81e38 authored by Haoxiang Li's avatar Haoxiang Li
Browse files

[SV HIDL] Default implementation for Surround View

Bug: 148618804

Test: atest -c VtsHalSurroundViewV1_0TargetTest (tested together with Change-id I1c6bfa77adb699ab80337497aac4582861315bcd)

Change-Id: Ibc9e32d9cc6c93ca71f34bc54e3bdecdf2c4dba2
parent 6bdb811f
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
//
// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

cc_binary {
    name: "android.hardware.automotive.sv@1.0-service",
    vendor: true,
    relative_install_path: "hw",
    srcs: [
        "service.cpp",
        "SurroundViewService.cpp",
        "SurroundView2dSession.cpp",
        "SurroundView3dSession.cpp",
    ],
    init_rc: ["android.hardware.automotive.sv@1.0-service.rc"],
    vintf_fragments: ["android.hardware.automotive.sv@1.0-service.xml"],
    shared_libs: [
        "android.hardware.automotive.sv@1.0",
        "android.hidl.memory@1.0",
        "libbase",
        "libbinder",
        "libcutils",
        "libhardware",
        "libhidlbase",
        "liblog",
        "libui",
        "libutils",
        "libhidlmemory",
    ],

    cflags: [
        "-O0",
        "-g",
    ],
}
+240 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "SurroundView2dSession.h"

#include <utils/Log.h>
#include <utils/SystemClock.h>

namespace android {
namespace hardware {
namespace automotive {
namespace sv {
namespace V1_0 {
namespace implementation {

SurroundView2dSession::SurroundView2dSession() :
    mStreamState(STOPPED) {
    mEvsCameraIds = {"0" , "1", "2", "3"};

    mConfig.width = 640;
    mConfig.blending = SvQuality::HIGH;

    framesRecord.frames.svBuffers.resize(1);
    framesRecord.frames.svBuffers[0].viewId = 0;
    framesRecord.frames.svBuffers[0].hardwareBuffer.nativeHandle =
        new native_handle_t();
    framesRecord.frames.svBuffers[0].hardwareBuffer.description[0] =
        mConfig.width;
    framesRecord.frames.svBuffers[0].hardwareBuffer.description[1] =
        mConfig.width * 3 / 4;
}

// Methods from ::android::hardware::automotive::sv::V1_0::ISurroundViewSession
Return<SvResult> SurroundView2dSession::startStream(
    const sp<ISurroundViewStream>& stream) {
    ALOGD("SurroundView2dSession::startStream");
    std::lock_guard<std::mutex> lock(mAccessLock);

    if (mStreamState != STOPPED) {
        ALOGE("ignoring startVideoStream call"
              "when a stream is already running.");
        return SvResult::INTERNAL_ERROR;
    }

    mStream = stream;

    ALOGD("Notify SvEvent::STREAM_STARTED");
    mStream->notify(SvEvent::STREAM_STARTED);

    // Start the frame generation thread
    mStreamState = RUNNING;
    mCaptureThread = std::thread([this](){ generateFrames(); });

    return SvResult::OK;
}

Return<void> SurroundView2dSession::stopStream() {
    ALOGD("SurroundView2dSession::stopStream");
    std::unique_lock <std::mutex> lock(mAccessLock);

    if (mStreamState == RUNNING) {
        // Tell the GenerateFrames loop we want it to stop
        mStreamState = STOPPING;

        // Block outside the mutex until the "stop" flag has been acknowledged
        // We won't send any more frames, but the client might still get some
        // already in flight
        ALOGD("Waiting for stream thread to end...");
        lock.unlock();
        mCaptureThread.join();
        lock.lock();

        mStreamState = STOPPED;
        mStream = nullptr;
        ALOGD("Stream marked STOPPED.");
    }

    return android::hardware::Void();
}

Return<void> SurroundView2dSession::doneWithFrames(
    const SvFramesDesc& svFramesDesc){
    ALOGD("SurroundView2dSession::doneWithFrames");
    std::unique_lock <std::mutex> lock(mAccessLock);

    framesRecord.inUse = false;

    (void)svFramesDesc;
    return android::hardware::Void();
}

// Methods from ISurroundView2dSession follow.
Return<void> SurroundView2dSession::get2dMappingInfo(
    get2dMappingInfo_cb _hidl_cb) {
    ALOGD("SurroundView2dSession::get2dMappingInfo");
    std::unique_lock <std::mutex> lock(mAccessLock);

    Sv2dMappingInfo info;
    info.width = 8; // keeps ratio to 4:3
    info.height = 6;
    info.center.isValid = true;
    info.center.x = 0;
    info.center.y = 0;
    _hidl_cb(info);
    return android::hardware::Void();
}

Return<SvResult> SurroundView2dSession::set2dConfig(
    const Sv2dConfig& sv2dConfig) {
    ALOGD("SurroundView2dSession::setConfig");
    std::unique_lock <std::mutex> lock(mAccessLock);

    mConfig.width = sv2dConfig.width;
    mConfig.blending = sv2dConfig.blending;
    ALOGD("Notify SvEvent::CONFIG_UPDATED");
    mStream->notify(SvEvent::CONFIG_UPDATED);

    return SvResult::OK;
}

Return<void> SurroundView2dSession::get2dConfig(get2dConfig_cb _hidl_cb) {
    ALOGD("SurroundView2dSession::getConfig");
    std::unique_lock <std::mutex> lock(mAccessLock);

    _hidl_cb(mConfig);
    return android::hardware::Void();
}

Return<void> SurroundView2dSession::projectCameraPoints(
        const hidl_vec<Point2dInt>& points2dCamera,
        const hidl_string& cameraId,
        projectCameraPoints_cb _hidl_cb) {
    ALOGD("SurroundView2dSession::projectCameraPoints");
    std::unique_lock <std::mutex> lock(mAccessLock);

    bool cameraIdFound = false;
    for (auto evsCameraId : mEvsCameraIds) {
      if (cameraId == evsCameraId) {
          cameraIdFound = true;
          ALOGI("Camera id found.");
          break;
      }
    }

    if (!cameraIdFound) {
        ALOGE("Camera id not found.");
        _hidl_cb(hidl_vec<Point2dFloat>());
        return android::hardware::Void();
    }

    hidl_vec<Point2dFloat> outPoints;
    outPoints.resize(points2dCamera.size());

    int width = mConfig.width;
    int height = mConfig.width * 3 / 4;
    for (int i=0; i<points2dCamera.size(); i++) {
        // Assuming all the points in the image frame can be projected into 2d
        // Surround View space. Otherwise cannot.
        if (points2dCamera[i].x < 0 || points2dCamera[i].y > width-1 ||
            points2dCamera[i].x < 0 || points2dCamera[i].y > height-1) {
            ALOGW("SurroundView2dSession::projectCameraPoints "
                  "gets invalid 2d camera points. Ignored");
            outPoints[i].isValid = false;
            outPoints[i].x = 10000;
            outPoints[i].y = 10000;
        } else {
            outPoints[i].isValid = true;
            outPoints[i].x = 0;
            outPoints[i].y = 0;
        }
    }

    _hidl_cb(outPoints);
    return android::hardware::Void();
}

void SurroundView2dSession::generateFrames() {
    ALOGD("SurroundView2dSession::generateFrames");

    int sequenceId = 0;

    while(true) {
        {
            std::lock_guard<std::mutex> lock(mAccessLock);

            if (mStreamState != RUNNING) {
                // Break out of our main thread loop
                break;
            }

            framesRecord.frames.svBuffers[0].hardwareBuffer.description[0] =
                mConfig.width;
            framesRecord.frames.svBuffers[0].hardwareBuffer.description[1] =
                mConfig.width * 3 / 4;
        }

        usleep(100 * 1000);

        framesRecord.frames.timestampNs = elapsedRealtimeNano();
        framesRecord.frames.sequenceId = sequenceId++;

        {
            std::lock_guard<std::mutex> lock(mAccessLock);

            if (framesRecord.inUse) {
                ALOGD("Notify SvEvent::FRAME_DROPPED");
                mStream->notify(SvEvent::FRAME_DROPPED);
            } else {
                framesRecord.inUse = true;
                mStream->receiveFrames(framesRecord.frames);
            }
        }
    }

    // If we've been asked to stop, send an event to signal the actual
    // end of stream
    ALOGD("Notify SvEvent::STREAM_STOPPED");
    mStream->notify(SvEvent::STREAM_STOPPED);
}

}  // namespace implementation
}  // namespace V1_0
}  // namespace sv
}  // namespace automotive
}  // namespace hardware
}  // namespace android
+98 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <android/hardware/automotive/sv/1.0/types.h>
#include <android/hardware/automotive/sv/1.0/ISurroundViewStream.h>
#include <android/hardware/automotive/sv/1.0/ISurroundView2dSession.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>

#include <thread>

using namespace ::android::hardware::automotive::sv::V1_0;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::hidl_vec;
using ::android::sp;
using ::std::mutex;

namespace android {
namespace hardware {
namespace automotive {
namespace sv {
namespace V1_0 {
namespace implementation {

class SurroundView2dSession : public ISurroundView2dSession {
public:
    SurroundView2dSession();

    // Methods from ::android::hardware::automotive::sv::V1_0::ISurroundViewSession.
    Return<SvResult> startStream(
        const sp<ISurroundViewStream>& stream) override;
    Return<void> stopStream() override;
    Return<void> doneWithFrames(const SvFramesDesc& svFramesDesc) override;

    // Methods from ISurroundView2dSession follow.
    Return<void> get2dMappingInfo(get2dMappingInfo_cb _hidl_cb) override;
    Return<SvResult> set2dConfig(const Sv2dConfig& sv2dConfig) override;
    Return<void> get2dConfig(get2dConfig_cb _hidl_cb) override;
    Return<void> projectCameraPoints(
        const hidl_vec<Point2dInt>& points2dCamera,
        const hidl_string& cameraId,
        projectCameraPoints_cb _hidl_cb) override;

    // TODO(tanmayp): Make private and add set/get method.
    // Stream subscribed for the session.
    sp<ISurroundViewStream> mStream;

private:
    void generateFrames();

    enum StreamStateValues {
        STOPPED,
        RUNNING,
        STOPPING,
        DEAD,
    };
    StreamStateValues mStreamState;

    Sv2dConfig mConfig;

    std::thread mCaptureThread; // The thread we'll use to synthesize frames

    struct FramesRecord {
        SvFramesDesc frames;
        bool inUse = false;
    };

    FramesRecord framesRecord;

    // Synchronization necessary to deconflict mCaptureThread from the main service thread
    std::mutex mAccessLock;

    std::vector<std::string> mEvsCameraIds;
};

}  // namespace implementation
}  // namespace V1_0
}  // namespace sv
}  // namespace automotive
}  // namespace hardware
}  // namespace android
+310 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "SurroundView3dSession.h"

#include <set>

#include <utils/Log.h>
#include <utils/SystemClock.h>

#include <android/hidl/memory/1.0/IMemory.h>
#include <hidlmemory/mapping.h>

using ::android::hidl::memory::V1_0::IMemory;
using ::android::hardware::hidl_memory;

namespace android {
namespace hardware {
namespace automotive {
namespace sv {
namespace V1_0 {
namespace implementation {

SurroundView3dSession::SurroundView3dSession() :
    mStreamState(STOPPED){

    mEvsCameraIds = {"0" , "1", "2", "3"};

    mConfig.width = 640;
    mConfig.height = 480;
    mConfig.carDetails = SvQuality::HIGH;

    framesRecord.frames.svBuffers.resize(1);
    framesRecord.frames.svBuffers[0].viewId = 0;
    framesRecord.frames.svBuffers[0].hardwareBuffer.nativeHandle = new native_handle_t();
    framesRecord.frames.svBuffers[0].hardwareBuffer.description[0] = mConfig.width;
    framesRecord.frames.svBuffers[0].hardwareBuffer.description[1] = mConfig.height;
}

// Methods from ::android::hardware::automotive::sv::V1_0::ISurroundViewSession.
Return<SvResult> SurroundView3dSession::startStream(
    const sp<ISurroundViewStream>& stream) {
    ALOGD("SurroundView3dSession::startStream");
    std::lock_guard<std::mutex> lock(mAccessLock);

    if (mStreamState != STOPPED) {
        ALOGE("ignoring startVideoStream call when a stream is already running.");
        return SvResult::INTERNAL_ERROR;
    }

    if (mViews.empty()) {
        ALOGE("No views have been set for current Surround View 3d Session. "
              "Please call setViews before starting the stream.");
        return SvResult::VIEW_NOT_SET;
    }

    mStream = stream;

    ALOGD("Notify SvEvent::STREAM_STARTED");
    mStream->notify(SvEvent::STREAM_STARTED);

    // Start the frame generation thread
    mStreamState = RUNNING;
    mCaptureThread = std::thread([this](){ generateFrames(); });

    return SvResult::OK;
}

Return<void> SurroundView3dSession::stopStream() {
    ALOGD("SurroundView3dSession::stopStream");
    std::unique_lock <std::mutex> lock(mAccessLock);

    if (mStreamState == RUNNING) {
        // Tell the GenerateFrames loop we want it to stop
        mStreamState = STOPPING;

        // Block outside the mutex until the "stop" flag has been acknowledged
        // We won't send any more frames, but the client might still get some already in flight
        ALOGD("Waiting for stream thread to end...");
        lock.unlock();
        mCaptureThread.join();
        lock.lock();

        mStreamState = STOPPED;
        mStream = nullptr;
        ALOGD("Stream marked STOPPED.");
    }

    return android::hardware::Void();
}

Return<void> SurroundView3dSession::doneWithFrames(
    const SvFramesDesc& svFramesDesc){
    ALOGD("SurroundView3dSession::doneWithFrames");
    std::unique_lock <std::mutex> lock(mAccessLock);

    framesRecord.inUse = false;

    (void)svFramesDesc;
    return android::hardware::Void();
}

// Methods from ISurroundView3dSession follow.
Return<SvResult> SurroundView3dSession::setViews(const hidl_vec<View3d>& views) {
    ALOGD("SurroundView3dSession::stopStream");
    std::unique_lock <std::mutex> lock(mAccessLock);

    mViews.resize(views.size());
    for (int i=0; i<views.size(); i++) {
        mViews[i] = views[i];
    }

    return SvResult::OK;
}

Return<SvResult> SurroundView3dSession::set3dConfig(const Sv3dConfig& sv3dConfig) {
    ALOGD("SurroundView3dSession::set3dConfig");
    std::unique_lock <std::mutex> lock(mAccessLock);

    mConfig.width = sv3dConfig.width;
    mConfig.height = sv3dConfig.height;
    mConfig.carDetails = sv3dConfig.carDetails;
    ALOGD("Notify SvEvent::CONFIG_UPDATED");
    mStream->notify(SvEvent::CONFIG_UPDATED);

    return SvResult::OK;
}

Return<void> SurroundView3dSession::get3dConfig(get3dConfig_cb _hidl_cb) {
    ALOGD("SurroundView3dSession::get3dConfig");
    std::unique_lock <std::mutex> lock(mAccessLock);

    _hidl_cb(mConfig);
    return android::hardware::Void();
}

bool VerifyOverlayData(const OverlaysData& overlaysData) {
    // Check size of shared memory matches overlaysMemoryDesc.
    const int kVertexSize = 16;
    const int kIdSize = 2;
    int memDescSize = 0;
    for (auto overlayMemDesc : overlaysData.overlaysMemoryDesc) {
        memDescSize += kIdSize + kVertexSize * overlayMemDesc.verticesCount;
    }
    if (memDescSize != overlaysData.overlaysMemory.size()) {
        ALOGE("shared memory and overlaysMemoryDesc size mismatch.");
        return false;
    }

    // Map memory.
    sp<IMemory> pSharedMemory = mapMemory(overlaysData.overlaysMemory);
    if(pSharedMemory.get() == nullptr) {
        ALOGE("mapMemory failed.");
        return false;
    }

    // Get Data pointer.
    uint8_t* pData = (uint8_t*)((void*)pSharedMemory->getPointer());
    if (pData == nullptr) {
        ALOGE("Shared memory getPointer() failed.");
        return false;
    }

    int idOffset = 0;
    std::set<uint16_t> overlayIdSet;
    for (auto overlayMemDesc : overlaysData.overlaysMemoryDesc) {

        if (overlayIdSet.find(overlayMemDesc.id) != overlayIdSet.end()) {
            ALOGE("Duplicate id within memory descriptor.");
            return false;
        }
        overlayIdSet.insert(overlayMemDesc.id);

        if(overlayMemDesc.verticesCount < 3) {
            ALOGE("Less than 3 vertices.");
            return false;
        }

        if (overlayMemDesc.overlayPrimitive == OverlayPrimitive::TRIANGLES &&
                overlayMemDesc.verticesCount % 3 != 0) {
            ALOGE("Triangles primitive does not have vertices multiple of 3.");
            return false;
        }

        uint16_t overlayId = *((uint16_t*)(pData + idOffset));

        if (overlayId != overlayMemDesc.id) {
            ALOGE("Overlay id mismatch %d , %d", overlayId, overlayMemDesc.id);
            return false;
        }

        idOffset += kIdSize + (kVertexSize * overlayMemDesc.verticesCount);
    }

    return true;
}

Return<SvResult>  SurroundView3dSession::updateOverlays(
        const OverlaysData& overlaysData) {

    if(!VerifyOverlayData(overlaysData)) {
        ALOGE("VerifyOverlayData failed.");
        return SvResult::INVALID_ARG;
    }

    return SvResult::OK;
}

Return<void> SurroundView3dSession::projectCameraPointsTo3dSurface(
    const hidl_vec<Point2dInt>& cameraPoints,
    const hidl_string& cameraId,
    projectCameraPointsTo3dSurface_cb _hidl_cb) {

    std::vector<Point3dFloat> points3d;
    bool cameraIdFound = false;
    for (auto evsCameraId : mEvsCameraIds) {
      if (cameraId == evsCameraId) {
          cameraIdFound = true;
          ALOGI("Camera id found.");
          break;
      }
    }

    if (!cameraIdFound) {
        ALOGE("Camera id not found.");
        _hidl_cb(points3d);
        return android::hardware::Void();
    }

    for (const auto cameraPoint : cameraPoints) {
        Point3dFloat point3d;
        point3d.isValid = true;

        if (cameraPoint.x < 0 || cameraPoint.x >= mConfig.width-1 ||
                cameraPoint.y < 0 || cameraPoint.y >= mConfig.height-1) {
            ALOGE("Camera point out of bounds.");
            point3d.isValid = false;
        }
        points3d.push_back(point3d);
    }
    _hidl_cb(points3d);
    return android::hardware::Void();
}

void SurroundView3dSession::generateFrames() {
    ALOGD("SurroundView3dSession::generateFrames");

    int sequenceId = 0;

    while(true) {
        {
            std::lock_guard<std::mutex> lock(mAccessLock);

            if (mStreamState != RUNNING) {
                // Break out of our main thread loop
                break;
            }
        }

        usleep(100 * 1000);

        framesRecord.frames.timestampNs = elapsedRealtimeNano();
        framesRecord.frames.sequenceId = sequenceId++;

        framesRecord.frames.svBuffers.resize(mViews.size());
        for (int i=0; i<mViews.size(); i++) {
            framesRecord.frames.svBuffers[i].viewId = mViews[i].viewId;
            framesRecord.frames.svBuffers[i].hardwareBuffer.nativeHandle = new native_handle_t();
            framesRecord.frames.svBuffers[i].hardwareBuffer.description[0] = mConfig.width; // width
            framesRecord.frames.svBuffers[i].hardwareBuffer.description[1] = mConfig.height; // height
        }

        {
            std::lock_guard<std::mutex> lock(mAccessLock);

            if (framesRecord.inUse) {
                ALOGD("Notify SvEvent::FRAME_DROPPED");
                mStream->notify(SvEvent::FRAME_DROPPED);
            } else {
                framesRecord.inUse = true;
                mStream->receiveFrames(framesRecord.frames);
            }
        }
    }

    // If we've been asked to stop, send an event to signal the actual end of stream
    ALOGD("Notify SvEvent::STREAM_STOPPED");
    mStream->notify(SvEvent::STREAM_STOPPED);
}

}  // namespace implementation
}  // namespace V1_0
}  // namespace sv
}  // namespace automotive
}  // namespace hardware
}  // namespace android
+100 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <android/hardware/automotive/sv/1.0/types.h>
#include <android/hardware/automotive/sv/1.0/ISurroundViewStream.h>
#include <android/hardware/automotive/sv/1.0/ISurroundView3dSession.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>

#include <thread>

using namespace ::android::hardware::automotive::sv::V1_0;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::hidl_vec;
using ::android::sp;
using ::std::mutex;

namespace android {
namespace hardware {
namespace automotive {
namespace sv {
namespace V1_0 {
namespace implementation {

class SurroundView3dSession : public ISurroundView3dSession {
public:
    SurroundView3dSession();

    // Methods from ::android::hardware::automotive::sv::V1_0::ISurroundViewSession.
    Return<SvResult> startStream(
        const sp<ISurroundViewStream>& stream) override;
    Return<void> stopStream() override;
    Return<void> doneWithFrames(const SvFramesDesc& svFramesDesc) override;

    // Methods from ISurroundView3dSession follow.
    Return<SvResult> setViews(const hidl_vec<View3d>& views) override;
    Return<SvResult> set3dConfig(const Sv3dConfig& sv3dConfig) override;
    Return<void> get3dConfig(get3dConfig_cb _hidl_cb) override;
    Return<SvResult>  updateOverlays(const OverlaysData& overlaysData);
    Return<void> projectCameraPointsTo3dSurface(
        const hidl_vec<Point2dInt>& cameraPoints,
        const hidl_string& cameraId,
        projectCameraPointsTo3dSurface_cb _hidl_cb);

    // Stream subscribed for the session.
    // TODO(tanmayp): Make private and add set/get method.
    sp<ISurroundViewStream> mStream;

private:
    void generateFrames();

    enum StreamStateValues {
        STOPPED,
        RUNNING,
        STOPPING,
        DEAD,
    };
    StreamStateValues mStreamState;

    std::thread mCaptureThread; // The thread we'll use to synthesize frames

    struct FramesRecord {
        SvFramesDesc frames;
        bool inUse = false;
    };

    FramesRecord framesRecord;

    // Synchronization necessary to deconflict mCaptureThread from the main service thread
    std::mutex mAccessLock;

    std::vector<View3d> mViews;

    Sv3dConfig mConfig;

    std::vector<std::string> mEvsCameraIds;
};

}  // namespace implementation
}  // namespace V1_0
}  // namespace sv
}  // namespace automotive
}  // namespace hardware
}  // namespace android
Loading