126 lines
4.2 KiB
C++
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
|