1. 实时获取rtsp流数据
功能描述
CamerPicUtil 类主要用于从 RTSP 流中读取视频帧,并将其转换为 QImage 格式,然后通过信号 signal_sendPic 发送出去。该类可以通过调用 doWork 方法开始工作,并且可以通过调用 stopRun 方法停止工作。
camerpicutil.h
// camerpicutil.h 文件
#ifndef CAMERPICUTIL_H
#define CAMERPICUTIL_H
#include <QObject>
#include <QCoreApplication>
// CamerPicUtil 类,继承自 QObject,用于处理摄像头图片的获取和处理
class CamerPicUtil : public QObject
{
Q_OBJECT
public:
// 构造函数,接收 RTSP 地址、组索引、摄像头索引和父对象指针
// url: RTSP 流的地址
// group_index: 组索引,用于标识不同的组
// camer_index: 摄像头索引,用于标识同一组内的不同摄像头
// parent: 父对象指针,默认为 nullptr
explicit CamerPicUtil(QString url, int group_index, int camer_index, QObject *parent = nullptr);
// 析构函数
~CamerPicUtil();
// 开始工作的方法,用于读取 RTSP 流并处理视频帧
void doWork();
public slots:
// 停止运行的槽函数,用于停止视频帧的读取和处理
void stopRun();
signals:
// 发送图片的信号,当处理完一帧视频后,通过该信号发送处理后的 QImage 以及组索引和摄像头索引
// image: 处理后的 QImage 指针
// group_index: 组索引
// camer_index: 摄像头索引
void signal_sendPic(QImage *image, int group_index, int camer_index);
private:
// RTSP 流的地址
QString m_rspturl;
// 控制是否继续运行的标志位
bool m_isRun = true;
// 组索引
int m_group_index = 1;
// 摄像头索引
int m_camer_index = 1;
};
#endif // CAMERPICUTIL_H
camerpicutil.cpp
// camerpicutil.cpp 文件
#include "camerpicutil.h"
#include "qthread.h"
#include <QDebug>
#include <QDateTime>
#include <QImage>
// 引入 FFmpeg 相关的 C 库
extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
#include <libavutil/opt.h>
#include <libavutil/channel_layout.h>
#include <libavutil/common.h>
#include <libavutil/imgutils.h>
#include <libavutil/mathematics.h>
#include <libavutil/samplefmt.h>
}
// 构造函数的实现
CamerPicUtil::CamerPicUtil(QString url, int group_index, int camer_index, QObject *parent)
: QObject{parent}
{
// 保存 RTSP 流的地址
m_rspturl = url;
// 打印 RTSP 地址,用于调试
qDebug() << "**********" << url;
// 保存组索引
m_group_index = group_index;
// 保存摄像头索引
m_camer_index = camer_index;
}
// 析构函数的实现
CamerPicUtil::~CamerPicUtil()
{
// 打印析构信息,用于调试
qDebug() << "~CamerPicUtil";
}
// 开始工作的方法实现
void CamerPicUtil::doWork()
{
// 视频流所在流序列中的索引,初始化为 -1 表示未找到
int videoStreamIndex = -1;
// 默认返回值,用于存储 FFmpeg 函数的返回结果
int ret = 0;
// 需要的 FFmpeg 相关变量并初始化
// AVFormatContext 用于存储输入或输出的格式信息
AVFormatContext *fmtCtx = NULL;
// AVPacket 用于存储压缩的音视频数据
AVPacket *pkt = NULL;
// AVCodecContext 用于存储解码器的上下文信息
AVCodecContext *codecCtx = NULL;
// AVCodecParameters 用于存储编解码器的参数信息
AVCodecParameters *avCodecPara = NULL;
// 分配一个 AVFrame 用于存储 YUV 格式的视频帧
AVFrame *yuvFrame = av_frame_alloc();
// 分配一个 AVFrame 用于存储 RGB 格式的视频帧
AVFrame *rgbFrame = av_frame_alloc();
// 用于设置 FFmpeg 的选项
AVDictionary* options = NULL;
// 设置 RTSP 传输方式为 TCP
av_dict_set(&options, "rtsp_transport", "tcp", 0);
// 设置超时断开链接时间,单位为微秒
av_dict_set(&options, "stimeout", "5000000", 0);
// 使用 do-while(0) 结构确保资源的正确释放
do {
// 分配一个 AVFormatContext,FFMPEG 所有的操作都要通过这个 AVFormatContext 来进行
fmtCtx = avformat_alloc_context();
// 打开 RTSP 流
if (avformat_open_input(&fmtCtx, m_rspturl.toLatin1().data(), NULL, &options) != 0) {
// 打开失败,打印错误信息并跳出循环
printf("cannot open video file\n");
break;
}
// 获取视频流信息
if ((ret = avformat_find_stream_info(fmtCtx, NULL)) < 0) {
// 获取失败,打印错误信息并跳出循环
printf("cannot retrive video info\n");
break;
}
// 循环查

最低0.47元/天 解锁文章
761

被折叠的 条评论
为什么被折叠?



