ZBLOG

#include #include #include int main(int argc, char* argv[]) { // 初始化GStreamer gst_init(&argc, &argv); // 创建GStreamer管道字符串,这里需要根据你的系统设置进行调整 const char* pipelineStr = "v4l2src device= /de...

当然,可以将你的代码封装成一个类,以便于更好地管理和重用。以下是一个示例的 VideoCapture 类,它封装了 GStreamer 和 OpenCV 的功能:

#include <iostream>
#include <opencv2/opencv.hpp>
#include <gst/gst.h>

class VideoCapture {
public:
    VideoCapture(const std::string& device)
        : pipeline(nullptr), appsink(nullptr) {
        // 初始化GStreamer
        gst_init(nullptr, nullptr);
        
        // 创建GStreamer管道字符串
        std::string pipelineStr = "v4l2src device=" + device + " ! videoconvert ! appsink name=sink";
        
        // 创建GStreamer管道
        pipeline = gst_parse_launch(pipelineStr.c_str(), nullptr);
        
        if (!pipeline) {
            throw std::runtime_error("Failed to create GStreamer pipeline.");
        }

        // 获取appsink元素并设置其属性
        appsink = gst_bin_get_by_name(GST_BIN(pipeline), "sink");
        g_object_set(appsink, "emit-signals", TRUE, NULL);

        // 启动管道
        gst_element_set_state(pipeline, GST_STATE_PLAYING);
    }

    ~VideoCapture() {
        if (pipeline) {
            // 停止管道并清理资源
            gst_element_set_state(pipeline, GST_STATE_NULL);
            gst_object_unref(pipeline);
        }
    }

    void capture() {
        cv::Mat frame;
        
        while (true) {
            GstSample* sample = nullptr;
            g_signal_emit_by_name(appsink, "pull-sample", &sample);

            if (sample) {
                GstBuffer* buffer = gst_sample_get_buffer(sample);
                GstCaps* caps = gst_sample_get_caps(sample);  // 获取caps
                
                if (caps) {
                    GstStructure* structure = gst_caps_get_structure(caps, 0);  // 获取第一个结构体
                    int width, height;

                    // 提取宽度和高度信息
                    gst_structure_get_int(structure, "width", &width);
                    gst_structure_get_int(structure, "height", &height);

                    GstMapInfo info;
                    if (gst_buffer_map(buffer, &info, GST_MAP_READ)) {
                        frame = cv::Mat(cv::Size(width, height), CV_8UC3, info.data).clone();  // 使用clone确保数据不被修改

                        cv::imshow("HDMI IN Video", frame);
                        cv::waitKey(1);  // 添加等待以更新窗口

                        gst_buffer_unmap(buffer, &info);
                    }
                }
                
                // 释放样本
                gst_sample_unref(sample);
            }
            
            if (cv::waitKey(30) >= 0) break;  // 添加退出机制,比如按任意键退出循环
        }
    }

private:
    GstElement* pipeline;
    GstElement* appsink;
};

int main(int argc, char* argv[]) {
    try {
        VideoCapture videoCapture("/dev/video0");
        videoCapture.capture();
    } catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
    }

    return 0;
}

使用说明:

  1. 初始化: 在构造函数中,传入设备路径,例如 "/dev/video0"
  2. 捕获视频: 调用 capture() 方法开始从视频源捕获帧。
  3. 析构函数: 确保在对象销毁时停止 GStreamer 管道,并释放资源。

注意事项:

  • 根据实际情况调整 pipelineStr 字符串中的元素。
  • 错误处理方面可以进一步增强,例如针对每个可能失败的操作进行异常捕捉。


    内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=7608

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?