/* * Copyright (C) 2021 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 "fake-pipeline2/Base.h" #include "EmulatedFakeRotatingCameraDevice.h" #include #include #include #include #include namespace android { class CameraRotator : private Thread, public virtual RefBase { public: CameraRotator(int w, int h); ~CameraRotator(); status_t startUp(); status_t shutDown(); void setExposureTime(uint64_t ns); void setFrameDuration(uint64_t ns); void setSensitivity(uint32_t gain); /* * Each Buffer in "buffers" must be at least stride*height*2 bytes in size. */ void setDestinationBuffers(Buffers *buffers); /* * To simplify tracking the sensor's current frame. */ void setFrameNumber(uint32_t frameNumber); /* * Synchronizing with sensor operation (vertical sync). */ /* * Wait until the sensor outputs its next vertical sync signal, meaning it * is starting readout of its latest frame of data. * * Returns: * true if vertical sync is signaled; false if the wait timed out. */ bool waitForVSync(nsecs_t reltime); /* * Wait until a new frame has been read out, and then return the time * capture started. May return immediately if a new frame has been pushed * since the last wait for a new frame. * * Returns: * true if new frame is returned; false if timed out. */ bool waitForNewFrame(nsecs_t reltime, nsecs_t *captureTime); /* * Interrupt event servicing from the sensor. Only triggers for sensor * cycles that have valid buffers to write to. */ struct CameraRotatorListener { enum Event { EXPOSURE_START, }; virtual void onCameraRotatorEvent(uint32_t frameNumber, Event e, nsecs_t timestamp) = 0; virtual ~CameraRotatorListener(); }; void setCameraRotatorListener(CameraRotatorListener *listener); /* * Static Sensor Characteristics */ const uint32_t mWidth, mHeight; const uint32_t mActiveArray[4]; static const nsecs_t kExposureTimeRange[2]; static const nsecs_t kFrameDurationRange[2]; static const nsecs_t kMinVerticalBlank; static const int32_t kSensitivityRange[2]; static const uint32_t kDefaultSensitivity; static const char kHostCameraVerString[]; private: int32_t mLastRequestWidth, mLastRequestHeight; /* * Defines possible states of the emulated camera device object. */ enum EmulatedCameraDeviceState { // Object has been constructed. ECDS_CONSTRUCTED, // Object has been initialized. ECDS_INITIALIZED, // Object has been connected to the physical device. ECDS_CONNECTED, // Camera device has been started. ECDS_STARTED, }; // Object state. EmulatedCameraDeviceState mState; const char *mDeviceName; GraphicBufferAllocator* mGBA; GraphicBufferMapper* mGBM; // Always lock before accessing control parameters. Mutex mControlMutex; /* * Control Parameters */ Condition mVSync; bool mGotVSync; uint64_t mFrameDuration; Buffers *mNextBuffers; uint32_t mFrameNumber; // Always lock before accessing readout variables. Mutex mReadoutMutex; /* * Readout Variables */ Condition mReadoutAvailable; Condition mReadoutComplete; Buffers *mCapturedBuffers; nsecs_t mCaptureTime; CameraRotatorListener *mListener; // Time of sensor startup (used for simulation zero-time point). nsecs_t mStartupTime; int32_t mHostCameraVer; bool mIsMinigbm; private: /* * Inherited Thread Virtual Overrides */ virtual status_t readyToRun() override; /* * CameraRotator capture operation main loop. */ virtual bool threadLoop() override; /* * Members only used by the processing thread. */ nsecs_t mNextCaptureTime; Buffers *mNextCapturedBuffers; void captureRGBA(uint32_t width, uint32_t height, uint32_t stride, int64_t *timestamp, buffer_handle_t* handle); void captureYU12(uint32_t width, uint32_t height, uint32_t stride, int64_t *timestamp, buffer_handle_t* handle); void captureRGBA(uint8_t *img, uint32_t width, uint32_t height, uint32_t stride, int64_t *timestamp); void captureYU12(uint8_t *img, uint32_t width, uint32_t height, uint32_t stride, int64_t *timestamp); void captureRGB(uint8_t *img, uint32_t width, uint32_t height, uint32_t stride, int64_t *timestamp); private: EmulatedFakeRotatingCameraDevice mRender; status_t queryStart(uint32_t pixel_format, int width, int height); status_t queryStart(); status_t queryStop(); status_t queryFrame(void* vframe, void* pframe, size_t vframe_size, size_t pframe_size, float r_scale, float g_scale, float b_scale, float exposure_comp, int64_t* frame_time); status_t queryFrame(int wdith, int height, uint32_t pixel_format, uint64_t offset, float r_scale, float g_scale, float b_scale, float exposure_comp, int64_t* frame_time); }; }; // end of namespace android