update uvc_camera

This commit is contained in:
linbo 2026-02-24 14:30:09 +08:00
parent d671729e1c
commit d79f493131
7 changed files with 671 additions and 345 deletions

View File

@ -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

View File

@ -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
} }

View File

@ -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)
# -------------------------------------------------------- # --------------------------------------------------------

View File

@ -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:

View File

@ -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)

View File

@ -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