今天小编给大家分享一下Qt+FFMPEG如何实现循环解码的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
可以设置延时函数-----遍历每一帧的信息进行打印
25(fps)*30(秒)=750帧
#ifndef VIDEODECODE_H #define VIDEODECODE_H #include <QObject> //当前C++兼容C语言 extern "C" { //avcodec:编解码(最重要的库) #include <libavcodec/avcodec.h> //avformat:封装格式处理 #include <libavformat/avformat.h> //swscale:视频像素数据格式转换 #include <libswscale/swscale.h> //avdevice:各种设备的输入输出 #include <libavdevice/avdevice.h> //avutil:工具库(大部分库都需要这个库的支持) #include <libavutil/avutil.h> } class videoDecode : public QObject { Q_OBJECT public: explicit videoDecode(QObject *parent = 0); //视频文件上下文格式 AVFormatContext* avformat_context; //编解码器上下文格式 AVCodecContext* avcodec_context; //解码器上下文格式 AVCodec* avcodec; signals: public slots: }; #endif // VIDEODECODE_H
#include "videodecode.h" #include<QDebug> #include<QCoreApplication> #include<QThread> //解码初始化操作 //1.注册所有组件 //2.打开视频输入文件 //3.查找视频流信息 //4.查找解码器 //5.打开解码器 videoDecode::videoDecode(QObject *parent) : QObject(parent) { qDebug()<<"1.注册所有组件"; av_register_all(); qDebug()<<"2.打开视频输入文件"; QString filename = QCoreApplication::applicationDirPath(); qDebug()<<"获取程序运行目录 "<<filename; QString cinputFilePath = "test.avi"; //本地视频文件放入程序运行目录 avformat_context = avformat_alloc_context(); //参数一:封装格式上下文->AVFormatContext->包含了视频信息(视频格式、大小等等...) //参数二:打开文件(入口文件)->url int avformat_open_result = avformat_open_input(&avformat_context,cinputFilePath.toStdString().c_str(),NULL,NULL); if (avformat_open_result != 0) { //获取异常信息 char* error_info = new char[32]; av_strerror(avformat_open_result, error_info, 1024); qDebug()<<QString("异常信息 %1").arg(error_info); }; qDebug()<<"3.查找视频流信息"; //参数一:封装格式上下文->AVFormatContext //参数二:配置 //返回值:0>=返回OK,否则失败 int avformat_find_stream_info_result = avformat_find_stream_info(avformat_context, NULL); if (avformat_find_stream_info_result < 0){ //获取失败 char* error_info = new char[32]; av_strerror(avformat_find_stream_info_result, error_info, 1024); qDebug()<<QString("异常信息 %1").arg(error_info); } qDebug()<<"4.查找解码器"; //第一点:获取当前解码器是属于什么类型解码器->找到了视频流 //音频解码器、视频解码器、字幕解码器等等... //获取视频解码器流引用 int av_stream_index = -1; for (int i = 0; i < avformat_context->nb_streams; ++i) { //循环遍历每一流 //视频流、音频流、字幕流等等... if (avformat_context->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO){ //找到了 av_stream_index = i; break; } } if (av_stream_index == -1) { qDebug()<<QString("没有找到视频流"); } //第二点:根据视频流->查找到视频解码器上下文->视频压缩数据 //编解码器上下文 avcodec_context = avformat_context->streams[av_stream_index]->codec; //第三点:根据解码器上下文->获取解码器ID avcodec = avcodec_find_decoder(avcodec_context->codec_id); if (avcodec == NULL) { qDebug()<<QString("没有找到视频解码器"); } qDebug()<<"5.打开解码器"; int avcodec_open2_result = avcodec_open2(avcodec_context,avcodec,NULL); if (avcodec_open2_result != 0) { char* error_info = new char[32]; av_strerror(avformat_find_stream_info_result, error_info, 1024); qDebug()<<QString("异常信息 %1").arg(error_info); } qDebug()<<"视频详细信息输出"; //此函数自动打印输入或输出的详细信息 av_dump_format(avformat_context, 0, cinputFilePath.toStdString().c_str(), 0); qDebug()<<"----------------解码准备工作完成-----------------"; qDebug()<<"----------------开始循环解码操作-----------------"; qDebug()<<"6.循环解码"; //读取帧数据换成到哪里->缓存到packet里面 AVPacket* av_packet = (AVPacket*)av_malloc(sizeof(AVPacket)); //解码的状态类型(0:表示解码完毕,非0:表示正在解码) int current_frame_index = 0; //>=0:说明有数据,继续读取 <0:说明读取完毕,结束 //从视频文件上下文中读取包--- 有数据就一直读取 while (av_read_frame(avformat_context,av_packet) >= 0) { //解码什么类型流(视频流、音频流、字幕流等等...) if (av_packet->stream_index == av_stream_index) { //遍历每一帧的信息进行打印 current_frame_index++; //延时操作 1秒显示25帧--1000/25=40 QThread::msleep(40); qDebug()<<QString("当前遍历第 %1 帧").arg(current_frame_index); } } qDebug()<<"7.关闭所有解码组件"; av_packet_free(&av_packet); //关闭流 avcodec_close(avcodec_context); avformat_free_context(avformat_context); }
#include "widget.h" #include <QApplication> #include"indexwin.h" #include<QGraphicsItem> //图元 #include<QGraphicsScene> //场景 #include<QGraphicsView> //视图 #include<QTransform> //变换 #include<QDebug> #include"myview.h" #include <QWidget> #include"usersdata.h" #include"registerwin.h" #include"sqlite3.h" #include"mysqlite.h"//数据库类 #include"videodecode.h" //当前C++兼容C语言 extern "C" { //avcodec:编解码(最重要的库) #include <libavcodec/avcodec.h> //avformat:封装格式处理 #include <libavformat/avformat.h> //swscale:视频像素数据格式转换 #include <libswscale/swscale.h> //avdevice:各种设备的输入输出 #include <libavdevice/avdevice.h> //avutil:工具库(大部分库都需要这个库的支持) #include <libavutil/avutil.h> } int main(int argc, char *argv[]) { QApplication a(argc, argv); qDebug()<<"sqlite3版本"<<sqlite3_libversion(); qDebug("------------------------------------------------------------------------"); qDebug("%s", avcodec_configuration()); qDebug("version: %d", avcodec_version()); qDebug("------------------------------------------------------------------------"); mySqlite::getInstance("app.db");//创建数据库 mySqlite::createUserTable("user");//创建用户表 videoDecode *p = new videoDecode; //开机动画 myView kaiji;//对象创建 kaiji.show();//调用方法 return a.exec(); }
以上就是“Qt+FFMPEG如何实现循环解码”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。