/* * Copyright (c) 2021 by Allwinnertech Co., Ltd. * * 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. */ #ifndef V4L2_CAMERA_HAL_STREAM_MANAGER_H_ #define V4L2_CAMERA_HAL_STREAM_MANAGER_H_ #include "common.h" #ifdef LOG_NDEBUG #undef LOG_NDEBUG #endif #if DBG_STREAM_MANAGER #undef NDEBUG #define LOG_NDEBUG 0 #else #define LOG_NDEBUG 1 #endif #include #include #include #include #include #include #include #include #include #include #include #include "CameraMetadata.h" #include "camera.h" #include "metadata/metadata.h" #include "v4l2_wrapper.h" #include "v4l2_camera.h" namespace v4l2_camera_hal { class CameraStream; class V4L2Camera; typedef struct { short refCnt; int frameNum; } FrameNumRef; class StreamManager : public android::RefBase { friend class CameraStream; friend class V4L2Camera; public: static std::shared_ptr NewStreamManager( std::shared_ptr device, std::shared_ptr camera); CameraStream* createStream(STREAM_SERIAL ss, uint32_t width, uint32_t height, int format, uint32_t usage, int isBlob, bool mergeStreamFlag); int configurateManager(STREAM_SERIAL ss); int start(STREAM_SERIAL ss); int stop(STREAM_SERIAL ss); int resultCallback(uint32_t frameNumber, struct timeval ts); int markFrameNumber(uint32_t frameNumber); int request(uint32_t frameNumber); ~StreamManager(); protected: class StreamYUVMEQ : public android::Thread { public: explicit StreamYUVMEQ(StreamManager* dev) : Thread(false), mStreamManager(dev), mRequestExit(false) {} void startThread() { run("StreamYUVmainEnqueue", android::PRIORITY_URGENT_DISPLAY); } void stopThread() { mRequestExit = true; } virtual bool threadLoop() { if (mRequestExit) { return false; } return mStreamManager->sYUVmainEnqueue(); } protected: StreamManager* mStreamManager; bool mRequestExit; }; class StreamYUVMDQ : public android::Thread { public: explicit StreamYUVMDQ(StreamManager* dev) : Thread(false), mStreamManager(dev), mRequestExit(false) {} void startThread() { run("StreamYUVmainDequeue", android::PRIORITY_URGENT_DISPLAY); } void stopThread() { mRequestExit = true; } virtual bool threadLoop() { if (mRequestExit) { return false; } return mStreamManager->sYUVmainDequeue(); } protected: StreamManager* mStreamManager; bool mRequestExit; const std::string mThreadName; }; class StreamYUVSEQ : public android::Thread { public: explicit StreamYUVSEQ(StreamManager* dev) : Thread(false), mStreamManager(dev), mRequestExit(false) {} void startThread() { run("StreamYUVsubEnqueue", android::PRIORITY_URGENT_DISPLAY); } void stopThread() { mRequestExit = true; } virtual bool threadLoop() { if (mRequestExit) { return false; } return mStreamManager->sYUVsubEnqueue(); } protected: StreamManager* mStreamManager; bool mRequestExit; }; class StreamYUVSDQ : public android::Thread { public: explicit StreamYUVSDQ(StreamManager* dev) : Thread(false), mStreamManager(dev), mRequestExit(false) {} void startThread() { run("StreamYUVsubDequeue", android::PRIORITY_URGENT_DISPLAY); } void stopThread() { mRequestExit = true; std::unique_lock lock(stream_lock_); } virtual bool threadLoop() { std::unique_lock lock(stream_lock_); if (mRequestExit) { return false; } return mStreamManager->sYUVsubDequeue(); } protected: StreamManager* mStreamManager; bool mRequestExit; const std::string mThreadName; std::mutex stream_lock_; }; private: StreamManager* instance; int mDrop_main_buffers; int mDrop_sub_buffers; StreamManager(std::shared_ptr device, std::unique_ptr gralloc, std::shared_ptr camera); bool sYUVmainEnqueue(); bool sYUVmainDequeue(); bool sYUVsubEnqueue(); bool sYUVsubDequeue(); std::shared_ptr device_; std::unique_ptr gralloc_; std::shared_ptr camera_; std::unique_ptr mConnection[MAX_STREAM]; std::shared_ptr mStream[MAX_STREAM]; std::shared_ptr mCameraStream[MAX_STREAM]; int64_t gtimemain; int64_t gtimesub; // Map frameNumber: refcnt about the buffer. std::unordered_map mMapFrameNumRef; std::mutex frameNumber_lock_; std::condition_variable frameNumber_condition_; int merge_stream_flag; /* Defines possible states of the stream thread. */ enum StreamStatus { /* Do not open steam. */ STREAM_STATE_NULL, /* Do not open steam. */ STREAM_STATE_PAUSED, /* Start steam. */ STREAM_STATE_STARTED, /* exit thread*/ STREAM_STATE_EXIT, }; StreamStatus mYUVMEThreadState; android::sp msYUVmainEnqueue; std::mutex msYUVmainEnqueueMutex; std::condition_variable msYUVmainEnqueueCond; StreamStatus mYUVMDThreadState; android::sp msYUVmainDequeue; std::mutex msYUVmainDequeueMutex; std::condition_variable msYUVmainDequeueCond; StreamStatus mYUVSEThreadState; android::sp msYUVsubEnqueue; std::mutex msYUVsubEnqueueMutex; std::condition_variable msYUVsubEnqueueCond; StreamStatus mYUVSDThreadState; android::sp msYUVsubDequeue; std::mutex msYUVsubDequeueMutex; std::condition_variable msYUVsubDequeueCond; DISALLOW_COPY_AND_ASSIGN(StreamManager); }; } // namespace v4l2_camera_hal #endif // V4L2_CAMERA_HAL_V4L2_CAMERA_H_