基于qt+ffmpeg的录像软件

一、环境搭建

1.1 编译环境

  • os:windows
  • 使用qt版本为5.14.2
  • 编译器MinGW 64-bit
  • IDE: Qt Creator

1.2 外部依赖库

  • ffmpeg:5.1.2(64位)
  • x264(64位)

1.3 qt配置外部依赖库

在这里插入图片描述

并将动态库,添加进系统环境变量

二、软件简介

2.1 系统架构

录像软件系统架构
该系统中,共有3个线程,分别是:

  • 主线程:负责各个模块的初始化,以及软件的逻辑处理
  • 录像线程:负责不断从摄像头获取原始图片数据,并添加到安全队列中
  • 数据保存线程:负责不断从安全队列中获取数据,并转换为合适的像素格式进行播放与保存

2.2 软件界面

软件界面效果图

  • 先点击获取设备,查找可用设备
  • 选择相应设备后,点击开始录像
  • 最后结束录像

2.3 代码

2.3.1 获取设备

#include "DeviceMsg.h"
#include <QDebug>

DeviceMsg::DeviceMsg()
    :m_iFormat(nullptr)
{
   
   
    avformat_network_init();
    avdevice_register_all();
}


QVector<QString> DeviceMsg::getDevice(const QString &deviceName)
{
   
   
    QVector<QString> v;
    AVDeviceInfoList *deviceList = nullptr;
    m_iFormat = av_find_input_format(deviceName.toStdString().data());
    if (!m_iFormat) {
   
   
        throw QString("无法找到输入格式"+deviceName);
    }

    int ret = avdevice_list_input_sources(m_iFormat, nullptr, nullptr, &deviceList);
    if (ret < 0) {
   
   
        throw QString("无法获取设备列表: 错误码 %1").arg(ret);
    } else if (deviceList) {
   
   
        for (int i = 0; i < deviceList->nb_devices; ++i) {
   
   
            QString s(deviceList->devices[i]->device_description);
            v.push_back(s);
        }
        avdevice_free_list_devices(&deviceList); // 释放资源
    } else {
   
   
        throw QString("设备列表为空");
    }
    return v;
}

const AVInputFormat *DeviceMsg::getIFormat() const
{
   
   
    return m_iFormat;
}

2.3.2 打开设备

#include "VideoDecode.h"
#include <QDebug>

VideoDecode::VideoDecode()
    :m_outPutFormat(AV_PIX_FMT_YUV420P)
{
   
   

}

void VideoDecode::init(const AVInputFormat *iFormat, const QString &deviceName)
{
   
   
    m_formatCtx = avformat_alloc_context();
    m_codecCtx = nullptr;
    const AVCodec *m_codec = nullptr;
    QString videoDevice = "video="+deviceName;
    int ret = avformat_open_input(&m_formatCtx,videoDevice.toUtf8().data(),iFormat,NULL);
    if(ret < 0)
    {
   
   
        throw QString("avformat_open_input error");
    }
    ret = avformat_find_stream_info(m_formatCtx, nullptr);
    if(ret < 0)
    {
   
   
        throw QString("avformat_find_stream_info error");
    }

    m_videoIndex = av_find_best_stream(m_formatCtx, AVMEDIA_TYPE_VIDEO,-1,-1,NULL,0);
    if(m_videoIndex == -1)
    {
   
   
        throw QString("找不到视频");
    }
    m_codec = avcodec_find_decoder(m_formatCtx->streams[m_videoIndex]->codecpar->codec_id);
    m_codecCtx = avcodec_alloc_context3(m_codec);
    avcodec_parameters_to_context(m_codecCtx,m_formatCtx->streams[m_videoIndex]->codecpar);

    //open codec
    if(avcodec_open2(m_codecCtx,m_codec,NULL))
    {
   
   
        throw QString("avcodec_open2 error");
    }

    //packet frame初始化
    m_packet = av_packet_alloc();
    m_frame = av_frame_alloc();

    //宽度、高度、格式设置
    m_frame->width = m_codecCtx->width;
    m_frame->height = m_codecCtx->height;
    m_frame->format = m_codecCtx->pix_fmt;
}

void VideoDecode::convert(AVFrame *dst, AVFrame *src, AVPixelFormat outPutFormat, AVPixelFormat inPutFormat)
{
   
   
    dst->width = m_codecCtx
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值