Qt+FFMPEG實(shí)現(xiàn)循環(huán)解碼詳解
一、結(jié)果

可以設(shè)置延時(shí)函數(shù)-----遍歷每一幀的信息進(jìn)行打印


25(fps)*30(秒)=750幀
二、解碼準(zhǔn)備工作+循環(huán)解碼相關(guān)操作
videodecode.h .cpp
#ifndef VIDEODECODE_H
#define VIDEODECODE_H
#include <QObject>
//當(dāng)前C++兼容C語言
extern "C"
{
//avcodec:編解碼(最重要的庫)
#include <libavcodec/avcodec.h>
//avformat:封裝格式處理
#include <libavformat/avformat.h>
//swscale:視頻像素?cái)?shù)據(jù)格式轉(zhuǎn)換
#include <libswscale/swscale.h>
//avdevice:各種設(shè)備的輸入輸出
#include <libavdevice/avdevice.h>
//avutil:工具庫(大部分庫都需要這個(gè)庫的支持)
#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()<<"獲取程序運(yùn)行目錄 "<<filename;
QString cinputFilePath = "test.avi"; //本地視頻文件放入程序運(yùn)行目錄
avformat_context = avformat_alloc_context();
//參數(shù)一:封裝格式上下文->AVFormatContext->包含了視頻信息(視頻格式、大小等等...)
//參數(shù)二:打開文件(入口文件)->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.查找視頻流信息";
//參數(shù)一:封裝格式上下文->AVFormatContext
//參數(shù)二:配置
//返回值: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.查找解碼器";
//第一點(diǎn):獲取當(dāng)前解碼器是屬于什么類型解碼器->找到了視頻流
//音頻解碼器、視頻解碼器、字幕解碼器等等...
//獲取視頻解碼器流引用
int av_stream_index = -1;
for (int i = 0; i < avformat_context->nb_streams; ++i) {
//循環(huán)遍歷每一流
//視頻流、音頻流、字幕流等等...
if (avformat_context->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO){
//找到了
av_stream_index = i;
break;
}
}
if (av_stream_index == -1)
{
qDebug()<<QString("沒有找到視頻流");
}
//第二點(diǎn):根據(jù)視頻流->查找到視頻解碼器上下文->視頻壓縮數(shù)據(jù)
//編解碼器上下文
avcodec_context = avformat_context->streams[av_stream_index]->codec;
//第三點(diǎn):根據(jù)解碼器上下文->獲取解碼器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()<<"視頻詳細(xì)信息輸出";
//此函數(shù)自動(dòng)打印輸入或輸出的詳細(xì)信息
av_dump_format(avformat_context, 0, cinputFilePath.toStdString().c_str(), 0);
qDebug()<<"----------------解碼準(zhǔn)備工作完成-----------------";
qDebug()<<"----------------開始循環(huán)解碼操作-----------------";
qDebug()<<"6.循環(huán)解碼";
//讀取幀數(shù)據(jù)換成到哪里->緩存到packet里面
AVPacket* av_packet = (AVPacket*)av_malloc(sizeof(AVPacket));
//解碼的狀態(tài)類型(0:表示解碼完畢,非0:表示正在解碼)
int current_frame_index = 0;
//>=0:說明有數(shù)據(jù),繼續(xù)讀取 <0:說明讀取完畢,結(jié)束
//從視頻文件上下文中讀取包--- 有數(shù)據(jù)就一直讀取
while (av_read_frame(avformat_context,av_packet) >= 0)
{
//解碼什么類型流(視頻流、音頻流、字幕流等等...)
if (av_packet->stream_index == av_stream_index)
{
//遍歷每一幀的信息進(jìn)行打印
current_frame_index++;
//延時(shí)操作 1秒顯示25幀--1000/25=40
QThread::msleep(40);
qDebug()<<QString("當(dāng)前遍歷第 %1 幀").arg(current_frame_index);
}
}
qDebug()<<"7.關(guān)閉所有解碼組件";
av_packet_free(&av_packet);
//關(guān)閉流
avcodec_close(avcodec_context);
avformat_free_context(avformat_context);
}main.cpp
#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"http://數(shù)據(jù)庫類
#include"videodecode.h"
//當(dāng)前C++兼容C語言
extern "C"
{
//avcodec:編解碼(最重要的庫)
#include <libavcodec/avcodec.h>
//avformat:封裝格式處理
#include <libavformat/avformat.h>
//swscale:視頻像素?cái)?shù)據(jù)格式轉(zhuǎn)換
#include <libswscale/swscale.h>
//avdevice:各種設(shè)備的輸入輸出
#include <libavdevice/avdevice.h>
//avutil:工具庫(大部分庫都需要這個(gè)庫的支持)
#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");//創(chuàng)建數(shù)據(jù)庫
mySqlite::createUserTable("user");//創(chuàng)建用戶表
videoDecode *p = new videoDecode;
//開機(jī)動(dòng)畫
myView kaiji;//對(duì)象創(chuàng)建
kaiji.show();//調(diào)用方法
return a.exec();
}到此這篇關(guān)于Qt+FFMPEG實(shí)現(xiàn)循環(huán)解碼詳解的文章就介紹到這了,更多相關(guān)Qt FFMPEG解碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用pybind11封裝C++結(jié)構(gòu)體作為參數(shù)的函數(shù)實(shí)現(xiàn)步驟
這篇文章主要介紹了用pybind11封裝C++結(jié)構(gòu)體作為參數(shù)的函數(shù)實(shí)現(xiàn)步驟,本文分步驟通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02
使用VSCode和VS2017編譯調(diào)試STM32程序的實(shí)現(xiàn)
這篇文章主要介紹了使用VSCode和VS2017編譯調(diào)試STM32程序的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
結(jié)合C++11的新特性來解析C++中的枚舉與聯(lián)合
這篇文章主要介紹了C++編程中的枚舉與聯(lián)合,結(jié)合了范圍(或強(qiáng)類型)enum class類型等C++11的新特性來講解,需要的朋友可以參考下2016-01-01
c++ 內(nèi)聯(lián)函數(shù)和普通函數(shù)的區(qū)別
內(nèi)聯(lián)函數(shù)是c++為了提高程序的運(yùn)行速度做的改進(jìn),那么內(nèi)聯(lián)函數(shù)和普通函數(shù)的區(qū)別是什么,本文就來詳細(xì)的介紹一下,感興趣的朋友可以了解一下2021-05-05
C語言中的函數(shù)指針基礎(chǔ)學(xué)習(xí)教程
這篇文章主要介紹了C語言中的函數(shù)指針基礎(chǔ)學(xué)習(xí)教程,包括函數(shù)指針作為參數(shù)來傳遞等重要知識(shí),需要的朋友可以參考下2016-04-04
C++ 賦值構(gòu)造函數(shù)注意點(diǎn)介紹
下面小編就為大家?guī)硪黄狢++ 賦值構(gòu)造函數(shù)注意點(diǎn)介紹。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-12-12

