Qt:使用FFmpeg解码视频流

Debug和Release載入不同動態庫:

//將lib文件放到對應工程目錄下,在.pro添加存放lib的路徑
LIBPATH += $$PWD/Library/Lib
//debug為active時處理LIBS += -L$$LIB_PATH -lOpengl32...
CONFIG(debug, debug|release){
    LIBS += -L$$LIBPATH -lOpengl32...}
else{
   LIBS += -L$$LIBPATH -lOpengl32 -lavcodec...}CONFIG(debug, debug|release):LIBS += -L$$LIBPATH -lOpengl32...
CONFIG(release, debug|release):LIBS += -L$$LIBPATH -lOpengl32 -lavcodec..
//在對應的debug或release目錄下添加使用的.dll文件

//本例中用到的库文件:
INCLUDEPATH += $$PWD/Dev/include
LIBPATH += $$PWD/Dev/lib
LIBS += -L$$LIBPATH -lavcodec -lavdevice -lavfilter -lavformat -lavutil -lpostproc -lswresample -lswscale

屏蔽QDebug()提示信息:在pro文件中添加:DEFINES+=QT_NO_DEBUG_OUTPUT

FFmpeg:
靜態庫版本:Static,只包含三個應用程式,不依賴動態庫可單獨運行;
動態庫版本:Shared,除應用程式外還包含dll動態庫;
開發者版本:Dev,包含lib文件和.h文件,但不包含dll文件。
使用ffmpeg要注意對應版本(如編譯器32位則使用32位的FFmpeg版本),ffmpeg庫為C文件,導入需在頭文件添加關鍵詞extetn “C”。

可將dll拷貝進lib,發佈時再拷貝dll進運行目錄或將dll拷貝進運行目錄。
檢查環境配置是否搭建成功:

unsigned version = avcodec_version();
QString ch = QString::number(version,10);
qDebug()<<"version: "<<version<<"\n配置信息:"<<avcodec_configuration();

注册FFmpeg组件:注册和初始化FFmpeg封装器和网络设备

av_register_all();
avformat_network_init();

QAudioOutput
是Qt中播放音频的类,要使用它,需要在pro中加入 QT += multimedia

程序代码:
(1)设置继承线程继承QThread

basicthread.h

#ifndef BASICTHREAD_H
#define BASICTHREAD_H
#include <QThread>
#include <QDebug>
extern "C"
{
   
    #include <libavcodec/avcodec.h>
    #include <libavformat/avformat.h>
    #include <libswscale/swscale.h>
    #include <libavdevice/avdevice.h>
    #include <libavformat/version.h>
    #include <libavutil/time.h>
    #include <libavutil/mathematics.h>
    #include "libswresample/swresample.h"
}
class basicthread:public QThread
{
   
    Q_OBJECT
public:
    basicthread(QObject * parent = nullptr);
    ~basicthread();
};

#endif // BASICTHREAD_H

basicthread.cpp

#include "basicthread.h"
basicthread::basicthread(QObject * parent):QThread(parent)
{
   
}
basicthread::~basicthread(){
   
    quit();
    wait();
    qDebug()<<"~BasicThread";
}

(2)初始化视频流线程:

initthread.h

#ifndef INITTHREAD_H
#define INITTHREAD_H
#include "basicthread.h"

class initthread : public basicthread
{
   
    Q_OBJECT
public:
    initthread(QObject*parent=nullptr);
    void closeinitthread();
    SwrContext*swrContext;
    AVCodecContext*audioCodecContext;
signals:
    void sendcontext(AVFormatContext*,AVCodecContext*,AVCodecContext*,SwrContext*);
protected:
    //重写虚函数run(),只有在此函数在新线程里,运行完毕后该线程生命周期结束
    virtual void run();
};
#endif // INITTHREAD_H

initthread.cpp

#include "initthread.h"

initthread::initthread(QObject*parent):basicthread(parent)
{
   
}

void initthread::run(){
   
    int videoStreamIndex=-1;int audioStreamIndex=-1;uint i;
      //注册库中所有可用的文件格式和解码器
      av_register_all();
      //初始化网络流格式,使用RTSP网络流时必须先执行
      avformat_network_init();
      //申請一個AVFormatContext結構的内存,並進行簡單初始化
      AVFormatContext* avFormatContext = avformat_alloc_context();

      //打開視頻流
      int ret=avformat_open_input(&avFormatContext,"C:\\Users\\shelly\\Desktop\\guitar.mp4",NULL,NULL);
      if(ret!=0){
   
          qDebug()<<"打開視頻流失敗";
           avformat_free_context(avFormatContext);
      }
      //讀取流數據包並獲取相關信息
      if(avformat_find_stream_info(avFormatContext,NULL)<0){
   
           qDebug()<<"獲取視頻流信息失敗";
           avformat_close_input(&avFormatContext);
          }

      for(i=0;i<avFormatContext->nb_streams;i++){
   
          //確定流格式是否為視頻
          if(avFormatContext->streams[i]->codecpar->codec_type==AVMEDIA_TYPE_VIDEO){
   
              videoStreamIndex=i; 
          }
          if(videoStreamIndex==-1){
   
              avformat_close_input(&avFormatContext);
              qDebug()<<"獲取視頻流索引失敗";
          }
          //確定流格式是否為音頻
          if(avFormatContext->streams[i]->codecpar->codec_type==AVMEDIA_TYPE_AUDIO){
   
              audioStreamIndex=i;
          }
      }
      //视频部分处理
      //根據編碼器ID獲取視頻劉解碼器
      AVCodec*videoCodec = avcodec_find_decoder(avFormatContext->streams[videoStreamIndex]->codecpar->codec_id);
      if(videoCodec==NULL){
   
          qDebug()<<"尋找视频解碼器失敗";
      }

      //获取视频编解码器上下文信息
      AVCodecContext*videoCodecContext = avcodec_alloc_context3(videoCodec);
      if(videoCodecContext==NULL){
   
          avformat_close_input(&avFormatContext);
          qDebug()
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值