ffmpeg解码RTSP/TCP视频流H.264(QT界面显示视频画面)

2023-05-16

源码下载地址: http://download.csdn.net/detail/liukang325/9489952

我用的ffmpeg版本为 ffmpeg-2.1.8.tar.bz2
版本低了恐怕有些头文件和API找不到。
在Linux下解压后编译,Linux下编译很简单,我这里生成的动态库:
./configure –enable-shared
make
就能找到各个so动态库文件。
移动位置后,记得手动链接 一下:

ln -s libavcodec.so.55 libavcodec.so
ln -s libavdevice.so.55 libavdevice.so
ln -s libavfilter.so.3 libavfilter.so
ln -s libavformat.so.55 libavformat.so
ln -s libavutil.so.52 libavutil.so
ln -s libswscale.so.2 libswscale.so

QT pro文件中记得加入:
INCLUDEPATH += ffmpeg/include
// windows下用这几个
win32: LIBS += ffmpeg/lib/libavcodec.dll.a ffmpeg/lib/libavfilter.dll.a ffmpeg/lib/libavformat.dll.a ffmpeg/lib/libswscale.dll.a ffmpeg/lib/libavutil.dll.a
// Linux下用这几个
LIBS += -lavcodec -lavdevice -lavfilter -lavformat -lavutil -lswscale -L./ffmpeg/so

我这里对外提供三个接口:

void VideoStream::setUrl(QString url)
{
    m_str_url = url;
}

void VideoStream::startStream()
{
    videoStreamIndex=-1;
    av_register_all();//注册库中所有可用的文件格式和解码器
    avformat_network_init();//初始化网络流格式,使用RTSP网络流时必须先执行
    pAVFormatContext = avformat_alloc_context();//申请一个AVFormatContext结构的内存,并进行简单初始化
    pAVFrame=av_frame_alloc();
    if (this->Init())
    {
        m_timerPlay->start();
    }
}
void VideoStream::stopStream()
{
    m_timerPlay->stop();

    avformat_free_context(pAVFormatContext);
    av_frame_free(&pAVFrame);
    sws_freeContext(pSwsContext);
}

里面与ffmpeg解码相关的私有变量:

    QMutex mutex;
    AVPicture  pAVPicture;
    AVFormatContext *pAVFormatContext;
    AVCodecContext *pAVCodecContext;
    AVFrame *pAVFrame;
    SwsContext * pSwsContext;
    AVPacket pAVPacket;

在QT里,用一个QLabel的对象来显示解码后的视频画面:

connect(this,SIGNAL(GetImage(QImage)),this,SLOT(SetImageSlots(QImage)));

...
void VideoStream::SetImageSlots(const QImage &image)
{
    if (image.height()>0){
        QPixmap pix = QPixmap::fromImage(image.scaled(m_i_w,m_i_h));
        m_label->setPixmap(pix);
    }
}

这里用的QTimer来进行一帧帧数据的解码,也可以用一个线程比如QThread来进行解码:

    m_timerPlay = new QTimer;
    m_timerPlay->setInterval(10);
    connect(m_timerPlay,SIGNAL(timeout()),this,SLOT(playSlots()));

    m_i_frameFinished = 0;

... 
bool VideoStream::Init()
{
    if(m_str_url.isEmpty())
        return false;
    //打开视频流
    int result=avformat_open_input(&pAVFormatContext, m_str_url.toStdString().c_str(),NULL,NULL);
    if (result<0){
        qDebug()<<"打开视频流失败";
        return false;
    }

    //获取视频流信息
    result=avformat_find_stream_info(pAVFormatContext,NULL);
    if (result<0){
        qDebug()<<"获取视频流信息失败";
        return false;
    }

    //获取视频流索引
    videoStreamIndex = -1;
    for (uint i = 0; i < pAVFormatContext->nb_streams; i++) {
        if (pAVFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
            videoStreamIndex = i;
            break;
        }
    }

    if (videoStreamIndex==-1){
        qDebug()<<"获取视频流索引失败";
        return false;
    }

    //获取视频流的分辨率大小
    pAVCodecContext = pAVFormatContext->streams[videoStreamIndex]->codec;
    videoWidth=pAVCodecContext->width;
    videoHeight=pAVCodecContext->height;

    avpicture_alloc(&pAVPicture,PIX_FMT_RGB24,videoWidth,videoHeight);

    AVCodec *pAVCodec;

    //获取视频流解码器
    pAVCodec = avcodec_find_decoder(pAVCodecContext->codec_id);
    pSwsContext = sws_getContext(videoWidth,videoHeight,PIX_FMT_YUV420P,videoWidth,videoHeight,PIX_FMT_RGB24,SWS_BICUBIC,0,0,0);

    //打开对应解码器
    result=avcodec_open2(pAVCodecContext,pAVCodec,NULL);
    if (result<0){
        qDebug()<<"打开解码器失败";
        return false;
    }

    qDebug()<<"初始化视频流成功";
    return true;
}

void VideoStream::playSlots()
{
    //一帧一帧读取视频
    if (av_read_frame(pAVFormatContext, &pAVPacket) >= 0){
        if(pAVPacket.stream_index==videoStreamIndex){
            qDebug()<<"开始解码"<<QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss");
            avcodec_decode_video2(pAVCodecContext, pAVFrame, &m_i_frameFinished, &pAVPacket);
            if (m_i_frameFinished){
                mutex.lock();
                sws_scale(pSwsContext,(const uint8_t* const *)pAVFrame->data,pAVFrame->linesize,0,videoHeight,pAVPicture.data,pAVPicture.linesize);
                //发送获取一帧图像信号
                QImage image(pAVPicture.data[0],videoWidth,videoHeight,QImage::Format_RGB888);
                emit GetImage(image);
                mutex.unlock();
            }
        }
    }
    av_free_packet(&pAVPacket);//释放资源,否则内存会一直上升
}

备注:
头文件包含及注意事项

//必须加以下内容,否则编译不能通过,为了兼容C和C99标准

#ifndef INT64_C
#define INT64_C
#define UINT64_C
#endif

//引入ffmpeg头文件
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavfilter/avfilter.h>
#include <libswscale/swscale.h>
#include <libavutil/frame.h>
}

启发:
setUrl(QString url);
这里的url 一般情况下是一个RTSP流的播放地址,如rtsp://192.168.1.123:554/stream1
但也可以是一个TCP流。
我这边测试的是一个本地的socket流,设url地址为 http://127.0.0.1:5858
可直接解码播放。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ffmpeg解码RTSP/TCP视频流H.264(QT界面显示视频画面) 的相关文章

  • opencv内存不足问题(OpenCV Error: Insufficient memory)

    最近在用opencv自带的函数haartraining训练分类器 xff0c 之前用的图片是20 20 xff0c 能训练出分类器 xff0c 后来换成了80 86 xff0c 就报错了 xff0c 报的错误是内存不足 xff0c 于是 x
  • ffmpeg 4.2.2 实现mp4转avi(修改官方remuxing例子)

    最近想把ffmpeg官方例子过一遍 xff0c 达到初步了解ffmpeg的目的 xff0c 本文只是给自己一个记录 xff0c 也是在网上没有找到一样的文章 xff0c 发出来供大家指点 直接使用官方demo xff0c 把mp4转换成av
  • 12.bss段的初始化

    12 bss段的初始化 在C代码 xff1a 有初始化全局的数据段 xff0c 局部的栈 xff0c malloc部分的堆 xff0c 未初始化的全局的bss段 从上面的编译的信息知道 xff1a Bss段的起始地址 xff1a 00010
  • pandas学习之df.rename()

    pandas学习之df rename df rename 用于更改行列的标签 xff0c 即行列的索引 可以传入一个字典或者一个函数 在数据预处理中 xff0c 比较常用 官方文档 xff1a DataFrame rename self m
  • java8操作两个集合List

    public static void main String args List lt String gt list1 61 new ArrayList lt String gt list1 add 34 1 34 list1 add 34
  • Atcoder AGC005 题解

    A STring 用类似括号匹配的方法搞一下即可 span class token macro property span class token directive keyword include span span class toke
  • CentOS-7安装桌面环境

    CentOS 7安装桌面环境 CentOS 7安装桌面环境 CentOS 7安装Server with GUI 设置为开机从桌面环境启动 yum y group install 39 Server with GUI 39 systemctl
  • [软件注册]Sublime 3 激活/注册码(key)

    偶然发现了一种sublime激活方式 使用的sublime3 1 1版本 亲试有效 Step1 配置 host文件 推荐使用 switchhost软件 可以快速变更host span class hljs number 127 0 span
  • 测试git能否连接github

    welcome to my blog 使用以下命令进行测试 ssh T git 64 github com 出现报错 ssh dispatch run fatal Connection to 13 250 177 223 port 22 S
  • vtk中实现3D模型(读取文件)

    xff08 xff09 VTK 坐标系统及空间变换 窗口 视图分割 mb5fed73533dfa9的技术博客 51CTO博客 VTK学习 xff08 三 xff09 VTK读取序列图像 灰信网 xff08 软件开发博客聚合 xff09 读取
  • centos中安装Python2.7

    转载于 xff1a 秋水逸冰 CentOS 6 8安装Python2 7 13 查看当前系统中的 Python 版本 python version 返回 Python 2 6 6 为正常 检查 CentOS 版本 cat etc redha
  • 安装tar.gz文件(无configure文件)

    如何安装tar gz文件 xff08 以webstorm为例 xff09 1 获取root权限并输入密码 xff1a su root 2 进入有该文件的目录下 xff08 以我的为例 xff0c 具体看你的文件在哪里 xff09 cd 下载
  • 游戏服务端框架之业务线程模型

    请求消息绑定线程策略的选择 在上一篇文章中 我们看到 消息是直接在网络框架的io线程中处理的 这样做有一个非常严重的缺陷 如果业务处理比较耗时 那么io线程接受消息的速度就会下降 严重影响io的吞吐量 典型的 我们应该另起线程池 专门用于异
  • 在WSL中使用GPU:WSL2 + Ubuntu 18.04 + CUDA + Gnome图形界面环境配置

    目录 引言1 确认Windows 10版本2 在Windows上安装WSL23 在Windows上安装CUDA on WSL驱动4 在WSL2中安装CUDA Toolkit3 测试CUDA是否能在WSL2中运作4 安装Gnome图形界面其他
  • Centos 开启路由转发实现全网互通

    只需在RouterSrv网关服务器上开启路由转发功能即可 root 64 RouterSrv vi etc sysctl conf net ipv4 ip forward 61 1 添加此行即可 root 64 localhost sysc
  • 虚拟机中配置外网环境

    文章目录 在虚拟机中配置外网环境 在虚拟机中配置外网环境 主机为 win10 xff0c 虚拟机中为 ubuntu 系统 xff0c 采用clash 1 xff0c 设置 Allow Lan xff0c 允许局域网访问 2 xff0c 虚拟
  • mysql 操作数据库(备份与恢复)

    一 直接把创建数据库的语句放到sql 文件中 xff1a php 写法 xff1a lt php mysql port 61 get mysql port cmd 61 US MYSQL BIN 34 mysql exe port 61 3
  • Go调用Python by go-python3

    确保python版本为3 7 conda create go python span class token assign left variable python span span class token operator 61 spa
  • linux下搭建maven私服

    maven私服我相信很多公司都有 xff0c 私服的好处有以下几点 xff1a 1 节省下载资源开销 jar包 xff08 不一定是jar xff0c 也可以是其他资源 xff09 都存在私服 xff0c 可以不必每次下载都去远程仓库去下载
  • git 安装包 最新 下载 快速 国内 镜像 地址

    下载git时 xff0c 先进官网看 https git scm com download win 然后发现几kb的网速 xff0c 这是要让我下一年么 xff0c 找了找网上有没有其他的镜像 xff0c 发现阿里有一个镜像 xff0c 下

随机推荐

  • docker笔记(四、docker部署beego打包后的二进制文件)

    在beego工程里 xff0c 使用go build可以将该工程打包成一个二进制文件 xff0c 那么这个二进制文件在docker里面该怎么部署呢 xff1f 先写一个简单的图片上传的demo xff0c 名字叫docker test 在工
  • LINUX服务器最简洁的HTTPS免费证书配置方法

    注意 xff1a 该方法已在多台服务器配置了免费的https证书 xff0c 无论是更新还是第一次配置都运行成功 xff1b 由于是免费版 xff0c 每个证书都只有三个月的有效期 xff0c 也无法保证安全和稳定性 xff0c 所以只建议
  • 【性能测试】获取性能系统指标之示例Python代码

    usr bin env python coding utf 8 import sys import datetime import time import psutil from ctypes import 34 34 34 性能测试示例P
  • select I/O 多路复用实现服务器聊天室功能

    基本概念 IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取 xff0c 它就通知该进程 IO多路复用适用如下场合 xff1a xff08 1 xff09 当客户处理多个描述字时 xff08 一般是交互式输入和网络套接口 x
  • iOS-使用Masnory实现UITableViewCell自适应高度

    在iOS开发当中 xff0c 如果涉及到UITableViewCell的一些复杂UI的绘制时难免会碰到这么一个难题 xff1a UITableViewCell的高度如何设置 xff01 的确 xff0c 我们就拿一个简单的例子来说 xff1
  • ubuntu中共享文件夹看不到

    博主的ubuntu安装VMwaretools后共享文件夹设置完发现在 mnt hgfs总看不到 经过多次摸索后终于可以了 首先要使用root用户登陆ubuntu 然后再安装VMwaretools 在设置共享文件夹 然后解决挂在的问题 1 设
  • keystore was tampered with,or password was incorrect解决办法

    利用keytool导入证书 xff0c 命令如下 keytool import alias HZZSQKJdianshang file HZZSQKJdianshang cer keystore trust jks storepass st
  • Convert Picture or Video to ascii

    一个利用ascii拼成的谷歌街景地图 xff01 http tllabs io asciistreetview 看上去效果真不错 xff01 除此之外 xff0c linux下面也有类似的ascii艺术 xff0c 比如 aview asc
  • texlive2015-6安装

    http www cnblogs com snake553 p 4831588 html CentOS6 5 下安装 texlive2015 并设置 ctex 中文套装 0 卸载旧版本的 texlive 0 1 卸载 texlive2007
  • ubuntu20.04 安装显卡驱动后开机卡住,无法进入登陆界面问题解决

    ubuntu20 04 安装显卡驱动后开机卡住 xff0c 无法进入登陆界面问题解决 进入recovery mode 禁用nvidia drm systemctl isolate multi user target modprobe r n
  • Linux环境变量失效,命令不可用

    背景 linux在修改完环境变量 etc profile后保存文件后 xff0c 发现大多数命令不可用 xff0c 只有少数如 xff1a cd pwd可以使用 xff1b 原因分析 1 etc profile文件中有无效字符或变量 xff
  • Ubuntu20.04安装MySQL5.7-实测3种方法(保姆级教程)

    最近生产系统系统需要使用MySQL5 7版本的数据库 xff0c 而Ubuntu20 04默认是8 0的版本 xff0c 折腾了一段时间后 xff0c 测试了3中方法 xff0c 在实际应用环境中测试成功 xff0c 因此发布出来给大家参考
  • 数据仓库的源数据类型

    数据仓库中集成了企业几乎所有的可以获取到的数据以用于数据分析和决策支持 xff0c 当然也包括了我在网站分析的数据来源一文中所提到的所有数据 这些进入到数据仓库中的数据无外乎三种类型 xff1a 结构化数据 半结构化数据 和非结构化数据 x
  • soj 1075 拓扑排序队列实现

    就是soj 拓扑排序的模板题吧 然后我中午把用队列实现的拓扑排序的方法看了下 晚上就打算来练一下这种纯模板 对于这实现的方法 xff0c 我的理解就是存下每个节点的入度以及它指向的其他节点 xff0c 由于指向多少个这个不太能确定所以用一个
  • poker

    include lt stdbool h gt include lt stdio h gt include lt stdlib h gt define NUM RANKS 13 define NUM SUTTS 4 define NUM C
  • vue实现筛选动态配置

    lt el form class 61 34 cellStyleForm 34 model 61 34 queryParams 34 ref 61 34 queryForm 34 v show 61 34 showSearch 34 inl
  • C. Good String Codeforces Round #560 (Div. 3)

    C Good String time limit per test 1 second memory limit per test 256 megabytes input standard input output standard outp
  • v4l2接口解析和摄像头数据采集

    V4L2接口解析 操作步骤 应用程序通过V4L2接口采集视频数据步骤 打开视频设备文件 xff0c 通过视频采集的参数初始化 xff0c 通过V4L2接口设置视频图像属性 申请若干视频采集的帧缓存区 xff0c 并将这些帧缓冲区从内核空间映
  • 阿里云cdn缓存命中查看

    我们在使用阿里云想知道CDN缓存命中 命中Hit X Cache HIT TCP MEM HIT dirn 9 435942540 上面的情况是命中的情况 不命中的情况miss X Cache MISS TCP MISS dirn 2 2
  • ffmpeg解码RTSP/TCP视频流H.264(QT界面显示视频画面)

    源码下载地址 http download csdn net detail liukang325 9489952 我用的ffmpeg版本为 ffmpeg 2 1 8 tar bz2 版本低了恐怕有些头文件和API找不到 在Linux下解压后编