update uvc_camera
This commit is contained in:
parent
d671729e1c
commit
d79f493131
@ -82,7 +82,6 @@ install(TARGETS proto LIBRARY DESTINATION lib)
|
|||||||
# include
|
# include
|
||||||
############################################################
|
############################################################
|
||||||
include_directories(
|
include_directories(
|
||||||
/usr/include/opencv4
|
|
||||||
/usr/local/include/
|
/usr/local/include/
|
||||||
${PROTO_BINARY_DIR}
|
${PROTO_BINARY_DIR}
|
||||||
${PROJECT_SOURCE_DIR}/include
|
${PROJECT_SOURCE_DIR}/include
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
realsense_cameras {
|
realsense_cameras {
|
||||||
id: "cam2"
|
id: "cam2"
|
||||||
serialNumber: "123456789012"
|
serialNumber: "243122074587"
|
||||||
width: 1280
|
width: 640
|
||||||
height: 720
|
height: 480
|
||||||
fps: 30
|
fps: 30
|
||||||
codec: "H265"
|
codec: "H265"
|
||||||
camera_mode: CAMERA_MODE_VIDEO
|
camera_mode: CAMERA_MODE_VIDEO
|
||||||
stream_mode: STREAM_MODE_RGBD
|
stream_mode: STREAM_MODE_RGBD
|
||||||
align_mode: ALIGN_MODE_COLOR
|
align_mode: ALIGN_MODE_COLOR
|
||||||
buffer_size: 30
|
buffer_size: 30
|
||||||
sync: true
|
sync: false
|
||||||
enable: false
|
enable: true
|
||||||
}
|
}
|
||||||
|
|
||||||
uvc_cameras {
|
uvc_cameras {
|
||||||
@ -23,5 +23,5 @@ uvc_cameras {
|
|||||||
camera_mode: CAMERA_MODE_VIDEO
|
camera_mode: CAMERA_MODE_VIDEO
|
||||||
stream_mode: STREAM_MODE_RGB
|
stream_mode: STREAM_MODE_RGB
|
||||||
buffer_size: 30
|
buffer_size: 30
|
||||||
enable: true
|
enable: false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
find_package(OpenCV REQUIRED)
|
|
||||||
add_library(realsense_camera SHARED src/realsense_camera.cpp)
|
add_library(realsense_camera SHARED src/realsense_camera.cpp)
|
||||||
|
|
||||||
target_include_directories(realsense_camera PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
target_include_directories(realsense_camera PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
@ -7,7 +5,7 @@ target_include_directories(realsense_camera PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
|||||||
add_library(cmvr_es::device::realsense_camera ALIAS realsense_camera) # ✅ 命名空间别名 OK
|
add_library(cmvr_es::device::realsense_camera ALIAS realsense_camera) # ✅ 命名空间别名 OK
|
||||||
|
|
||||||
# 链接 librealsense2
|
# 链接 librealsense2
|
||||||
target_link_libraries(realsense_camera PRIVATE realsense2 ${OpenCV_LIBS} )
|
target_link_libraries(realsense_camera PRIVATE realsense2 opencv_core opencv_imgproc opencv_videoio)
|
||||||
|
|
||||||
install(TARGETS realsense_camera LIBRARY DESTINATION lib)
|
install(TARGETS realsense_camera LIBRARY DESTINATION lib)
|
||||||
# --------------------------------------------------------
|
# --------------------------------------------------------
|
||||||
|
|||||||
@ -9,47 +9,9 @@
|
|||||||
#include <librealsense2/rs.hpp>
|
#include <librealsense2/rs.hpp>
|
||||||
#include <librealsense2/hpp/rs_internal.hpp>
|
#include <librealsense2/hpp/rs_internal.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace cmvr::device{
|
namespace cmvr::device{
|
||||||
enum StreamMode {RGBD_MODE, COLOR_MODE,DEPTH_MODE};
|
enum StreamMode {RGBD_MODE, COLOR_MODE,DEPTH_MODE};
|
||||||
struct FfmpegEncoderInfo {
|
|
||||||
std::string codec_name; // 编码器名称(如"h264"、"hevc")
|
|
||||||
int width = 0; // 图像宽度
|
|
||||||
int height = 0; // 图像高度
|
|
||||||
int fps = 0; // 帧率
|
|
||||||
int64_t frame_pts = 0;
|
|
||||||
bool bRunning = false; // 是否进行编码
|
|
||||||
AVCodecContext* codec_context = nullptr; // 编码器上下文
|
|
||||||
AVFrame* frame = nullptr; // 输入帧
|
|
||||||
AVPacket* packet = nullptr; // 输出包
|
|
||||||
SwsContext* sws_context = nullptr; // 图像转换上下文(如果需要格式转换)
|
|
||||||
|
|
||||||
// 析构函数:释放FFmpeg资源(核心!避免内存泄漏)
|
|
||||||
~FfmpegEncoderInfo() {
|
|
||||||
// 释放编码帧
|
|
||||||
if (frame) {
|
|
||||||
av_frame_free(&frame);
|
|
||||||
frame = nullptr;
|
|
||||||
}
|
|
||||||
// 释放编码包
|
|
||||||
if (packet) {
|
|
||||||
av_packet_free(&packet);
|
|
||||||
packet = nullptr;
|
|
||||||
}
|
|
||||||
// 释放编码器上下文
|
|
||||||
if (codec_context) {
|
|
||||||
avcodec_close(codec_context); // 关闭编码器
|
|
||||||
avcodec_free_context(&codec_context); // 释放上下文
|
|
||||||
codec_context = nullptr;
|
|
||||||
}
|
|
||||||
// 释放格式转换上下文
|
|
||||||
if (sws_context) {
|
|
||||||
sws_freeContext(sws_context);
|
|
||||||
sws_context = nullptr;
|
|
||||||
}
|
|
||||||
//std::cout << "FfmpegEncoderInfo resources released." << std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class RealsenseCamera final : public AbstractCamera {
|
class RealsenseCamera final : public AbstractCamera {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
find_package(OpenCV REQUIRED)
|
|
||||||
|
|
||||||
add_library(uvc_camera SHARED src/uvc_camera.cpp)
|
add_library(uvc_camera SHARED src/uvc_camera.cpp)
|
||||||
|
|
||||||
target_include_directories(uvc_camera PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
target_include_directories(uvc_camera PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
target_link_libraries(uvc_camera PUBLIC ${OpenCV_LIBS} glog)
|
target_link_libraries(uvc_camera PUBLIC glog opencv_core opencv_imgproc)
|
||||||
|
|
||||||
add_library(cmvr_es::device::uvc_camera ALIAS uvc_camera)
|
add_library(cmvr_es::device::uvc_camera ALIAS uvc_camera)
|
||||||
install(TARGETS uvc_camera LIBRARY DESTINATION lib)
|
install(TARGETS uvc_camera LIBRARY DESTINATION lib)
|
||||||
@ -1,24 +1,71 @@
|
|||||||
// uvc_camera.h
|
//
|
||||||
|
// Created by xtkuang on 2025/5/30.
|
||||||
|
//
|
||||||
|
|
||||||
#ifndef CMVR_ES_UVC_CAMERA_H
|
#ifndef CMVR_ES_UVC_CAMERA_H
|
||||||
#define CMVR_ES_UVC_CAMERA_H
|
#define CMVR_ES_UVC_CAMERA_H
|
||||||
|
|
||||||
#include "utils/base/include/ring_buffer.h"
|
#include "utils/base/include/ring_buffer.h"
|
||||||
#include "camera/abstract_camera.h"
|
#include "camera/abstract_camera.h"
|
||||||
|
|
||||||
// 使用新的FFmpeg封装类
|
//使用ffmpeg来编码保存视频文件
|
||||||
#include "common/utils/ffmpeg/include/CameraCapture.h"
|
#define USE_FFMPEG_ENCODER 1
|
||||||
#include "common/utils/ffmpeg/include/VideoFrameEncoder.h"
|
|
||||||
#include "common/utils/ffmpeg/include/VideoWriter.h"
|
#if USE_FFMPEG_ENCODER
|
||||||
|
#include "speaker/ffmpeg_speaker/include/ffmpeg_ptr.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace cmvr::device {
|
namespace cmvr::device {
|
||||||
enum CameraMode {PHOTO_MODE, VIDEO_MODE};
|
enum CameraMode {PHOTO_MODE, VIDEO_MODE};
|
||||||
|
|
||||||
|
|
||||||
struct ImageData
|
struct ImageData
|
||||||
{
|
{
|
||||||
|
//原始图像数据
|
||||||
cv::Mat rgbImage;
|
cv::Mat rgbImage;
|
||||||
|
//深度图原始数据
|
||||||
cv::Mat depthImage;
|
cv::Mat depthImage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FfmpegEncoderInfo {
|
||||||
|
std::string codec_name; // 编码器名称(如"h264"、"hevc")
|
||||||
|
int width = 0; // 图像宽度
|
||||||
|
int height = 0; // 图像高度
|
||||||
|
int fps = 0; // 帧率
|
||||||
|
int64_t frame_pts = 0;
|
||||||
|
bool bRunning = false; // 是否进行编码
|
||||||
|
AVCodecContext* codec_context = nullptr; // 编码器上下文
|
||||||
|
AVFrame* frame = nullptr; // 输入帧
|
||||||
|
AVPacket* packet = nullptr; // 输出包
|
||||||
|
SwsContext* sws_context = nullptr; // 图像转换上下文(如果需要格式转换)
|
||||||
|
|
||||||
|
// 析构函数:释放FFmpeg资源(核心!避免内存泄漏)
|
||||||
|
~FfmpegEncoderInfo() {
|
||||||
|
// 释放编码帧
|
||||||
|
if (frame) {
|
||||||
|
av_frame_free(&frame);
|
||||||
|
frame = nullptr;
|
||||||
|
}
|
||||||
|
// 释放编码包
|
||||||
|
if (packet) {
|
||||||
|
av_packet_free(&packet);
|
||||||
|
packet = nullptr;
|
||||||
|
}
|
||||||
|
// 释放编码器上下文
|
||||||
|
if (codec_context) {
|
||||||
|
avcodec_close(codec_context); // 关闭编码器
|
||||||
|
avcodec_free_context(&codec_context); // 释放上下文
|
||||||
|
codec_context = nullptr;
|
||||||
|
}
|
||||||
|
// 释放格式转换上下文
|
||||||
|
if (sws_context) {
|
||||||
|
sws_freeContext(sws_context);
|
||||||
|
sws_context = nullptr;
|
||||||
|
}
|
||||||
|
//std::cout << "FfmpegEncoderInfo resources released." << std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//USB摄像机
|
//USB摄像机
|
||||||
class UVCCamera final : public AbstractCamera {
|
class UVCCamera final : public AbstractCamera {
|
||||||
public:
|
public:
|
||||||
@ -35,41 +82,56 @@ namespace cmvr::device {
|
|||||||
void updateParams(const std::pair<std::string, std::string>& param) override;
|
void updateParams(const std::pair<std::string, std::string>& param) override;
|
||||||
void startRecording(const std::string &video_path) override;
|
void startRecording(const std::string &video_path) override;
|
||||||
void stopRecording() override;
|
void stopRecording() override;
|
||||||
|
void pauseRecording() override;
|
||||||
|
void resumeRecording() override;
|
||||||
|
// 初始化单个编码器的通用函数(复用逻辑,避免重复代码)
|
||||||
|
static bool initSingleEncoder(std::shared_ptr<FfmpegEncoderInfo>& encoder,
|
||||||
|
const std::string& codec_name,
|
||||||
|
int width, int height, int fps);
|
||||||
|
static bool encodeFrameWithEncoder(std::shared_ptr<FfmpegEncoderInfo>& encoder,const cv::Mat& frame,std::vector<uint8_t>& encoded_frame,bool& is_key);
|
||||||
void getEncodedFrame(StreamFrameData& frame_data, size_t& index) override;
|
void getEncodedFrame(StreamFrameData& frame_data, size_t& index) override;
|
||||||
|
|
||||||
bool startStreaming() override;
|
bool startStreaming() override;
|
||||||
void stopStreaming() override;
|
void stopStreaming() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void streaming_worker_();
|
void streaming_worker_();
|
||||||
|
void recording_worker_();
|
||||||
// 辅助函数
|
|
||||||
static bool convertAVFrameToMat(AVFrame* frame, cv::Mat& mat);
|
|
||||||
|
|
||||||
int fps_;
|
int fps_;
|
||||||
int width_;
|
int width_;
|
||||||
int height_;
|
int height_;
|
||||||
std::string serial_;
|
std::string serial_;
|
||||||
|
cv::VideoCapture cap_;
|
||||||
size_t buffer_size_;
|
size_t buffer_size_;
|
||||||
std::string codec_;
|
std::string codec_;
|
||||||
CameraMode mode_;
|
CameraMode mode_;
|
||||||
|
|
||||||
|
// std::shared_ptr<cv::Mat> current_image_;
|
||||||
std::shared_ptr<SPMCRingBuffer<StreamFrameData>> stream_frame_buffer_;
|
std::shared_ptr<SPMCRingBuffer<StreamFrameData>> stream_frame_buffer_;
|
||||||
std::string current_video_path_;
|
std::string current_video_path_;
|
||||||
|
|
||||||
std::mutex ctrl_mtx_{};
|
std::mutex ctrl_mtx_{};
|
||||||
|
std::unique_ptr<cv::VideoWriter> video_writer_;
|
||||||
std::shared_ptr<std::thread> stream_thread_;
|
std::shared_ptr<std::thread> stream_thread_;
|
||||||
|
std::shared_ptr<std::thread> recording_thread_;
|
||||||
|
|
||||||
// 新的FFmpeg封装类实例
|
|
||||||
std::unique_ptr<ffmpeg::CameraCapture> camera_capture_;
|
|
||||||
std::unique_ptr<ffmpeg::VideoFrameEncoder> video_encoder_;
|
|
||||||
std::unique_ptr<ffmpeg::VideoWriter> video_writer_;
|
|
||||||
|
|
||||||
// 用于临时存储最新帧
|
cv::Mat latest_frame_; // 存储最新帧
|
||||||
std::mutex latest_frame_mutex_;
|
std::mutex frame_mutex_; // 保护最新帧的访问
|
||||||
cv::Mat latest_rgb_frame_;
|
|
||||||
bool latest_frame_valid_ = false;
|
|
||||||
|
|
||||||
|
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 streamIndex_ = 0;
|
||||||
size_t recordingIndex_ = 0;
|
size_t recordingIndex_ = 0;
|
||||||
size_t getImageIndex_ = 0;
|
size_t getImageIndex_ = 0;
|
||||||
@ -83,4 +145,6 @@ namespace cmvr::device {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif //CMVR_ES_UVC_CAMERA_H
|
#endif //CMVR_ES_UVC_CAMERA_H
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user