cmvr-es/cmvr-es/devices/camera/uvc_camera/include/uvc_camera.h

126 lines
4.2 KiB
C++

//
// Created by xtkuang on 2025/5/30.
//
#ifndef CMVR_ES_UVC_CAMERA_H
#define CMVR_ES_UVC_CAMERA_H
#include <atomic>
#include <condition_variable>
#include "common/base/ring_buffer.h"
#include "camera/abstract_camera.h"
#include "devices/camera/common/include/camera_stream_encoder.h"
namespace cmvr::device {
struct ImageData
{
//原始图像数据
cv::Mat rgbImage;
//深度图原始数据
cv::Mat depthImage;
};
//USB摄像机
class UVCCamera final : public AbstractCamera {
public:
UVCCamera(const cmvr::config::UVCCameraConfig& camera);
~UVCCamera() override;
std::string typeName() const override { return "UVCCamera"; }
bool init() override;
bool start() override;
bool stop() override;
void getState(CameraState& state) override;
void getRGBImage(cv::Mat& color, Rs2Intrinsics& intrinsics) override;
void getDepthImage(cv::Mat& depth, Rs2Intrinsics& intrinsics) override;
void getRGBDImages(cv::Mat &color, cv::Mat &depth, Rs2Intrinsics& intrinsics) override;
void startRecording(const std::string &video_path) override;
void stopRecording() override;
void pauseRecording() override;
void resumeRecording() override;
void getEncodedFrame(StreamFrameData& frame_data, size_t& index) override;
bool getLatestEncodedFrame(StreamFrameData& frame_data, size_t& next_index) override;
bool startStreaming() override;
void stopStreaming() override;
private:
void streaming_worker_();
void recording_worker_();
void cleanup_recording_resources_();
bool open_capture_();
void close_capture_();
void capture_worker_();
bool wait_for_capture_frame_(AVFrame* frame,
uint64_t& last_sequence,
int64_t& capture_monotonic_ns,
int64_t& capture_utc_ns);
bool convert_capture_frame_to_bgr_(const AVFrame* frame, cv::Mat& bgr_frame);
static int interrupt_capture_(void* opaque);
int fps_;
int width_;
int height_;
int encode_width_;
int encode_height_;
std::string serial_;
size_t buffer_size_;
std::string codec_;
bool enable_stream_timestamp_{false};
CameraMode mode_;
// std::shared_ptr<cv::Mat> current_image_;
std::shared_ptr<SPMCRingBuffer<StreamFrameData>> stream_frame_buffer_;
std::string current_video_path_;
std::mutex ctrl_mtx_{};
std::shared_ptr<std::thread> stream_thread_;
std::shared_ptr<std::thread> recording_thread_;
std::shared_ptr<std::thread> capture_thread_;
AVFormatContext* capture_format_context_ = nullptr;
AVCodecContext* capture_decoder_context_ = nullptr;
AVBufferRef* capture_hw_device_context_ = nullptr;
SwsContext* capture_sws_context_ = nullptr;
int capture_video_stream_index_ = -1;
std::atomic<bool> capture_running_{false};
std::mutex capture_frame_mutex_;
std::mutex capture_conversion_mutex_;
std::condition_variable capture_frame_cv_;
AVFrame* latest_capture_frame_ = nullptr;
uint64_t latest_capture_sequence_ = 0;
int64_t latest_capture_monotonic_ns_ = 0;
int64_t latest_capture_utc_ns_ = 0;
std::string capture_error_;
std::string output_path_;
bool is_recording_ = false;
// ffmpeg录像
AVFormatContext* format_context_ = nullptr;
AVCodecContext* codec_context_ = nullptr;
AVStream* stream_ = nullptr;
AVFrame* frame_ = nullptr;
AVPacket* packet_ = nullptr;
SwsContext* sws_context_ = nullptr;
int frame_count_ = 0;
std::shared_ptr<FfmpegEncoderInfo> rgbEncoder_;//rgb图像编码
std::shared_ptr<FfmpegEncoderInfo> depthEncoder_;//深度图编码
size_t streamIndex_ = 0;
size_t recordingIndex_ = 0;
size_t getImageIndex_ = 0;
bool is_streaming_running = false;
bool is_recording_running = false;
int stream_count_ = 0;
config::UVCCameraConfig camera_;
};
}
#endif //CMVR_ES_UVC_CAMERA_H