https://ffmpeg.zeranoe.com/builds/
版本说明:
需要下载 Shared和Dev,放在文件夹。static可以不下载。
在.pro里添加lib和include路径:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = ffmpeg1
TEMPLATE = app
SOURCES += main.cpp\
widget.cpp
HEADERS += widget.h
FORMS += widget.ui
INCLUDEPATH +="D:\\Documents\\FFMpeg\\dev\\include"
LIBS += -LD:\Documents\FFMpeg\dev\lib -lavutil -lavformat -lavcodec -lavdevice -lavfilter -lpostproc -lswresample -lswscale
把shared里bin内容拷贝到exe目录下:
代码仓库: https://gitee.com/xundh/QT-Study/tree/master/sample5_ffmpeg1
#include "widget.h"
#include "ui_widget.h"
#include
#include
extern "C"{
#include
#include
#include
#include
}
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Delay(int msec){
QTime dieTime = QTime::currentTime().addMSecs(msec);
while(QTime::currentTime() < dieTime)
QCoreApplication::processEvents(QEventLoop::AllEvents,100);
}
void Widget::on_pushButton_clicked()
{
AVFormatContext *pFormatCtx;
int i,videoindex;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame , *pFrameRGB;
unsigned char *out_buffer;
AVPacket *packet;
int ret,got_picture;
struct SwsContext *img_convert_ctx;
char filepath[] = "D:/1.mp4";
// 初始化编解码库
av_register_all(); // 创建AVFormatContext对象,与码流相关的结构
pFormatCtx = avformat_alloc_context();
// 初始化pFormatCtx结构
if (avformat_open_input(&pFormatCtx, filepath, NULL, NULL) != 0){
qDebug() << "Couldn't open input stream. . " << endl;
return;
}
// 获取音频视频流数据信息
if(avformat_find_stream_info(pFormatCtx,NULL)<0){
qDebug() << "Couldn't find stream information. " << endl;
return;
}
videoindex = -1;
// nb_streams视音频流的个数,这里当查找到视频流时就中断了。
for(int i=0;inb_streams;i++){
if(pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO){
videoindex=i;
break;
}
}
if(videoindex==-1){
qDebug() << "Didn't find a video stream. " << endl;
return;
}
// 获取视频流编码结构
pCodecCtx = pFormatCtx->streams[videoindex]->codec;
// 查找解码器
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL){
qDebug() << "codec not found." << endl;
return;
}
// 用于初始化pCodecCtx结构
if(avcodec_open2(pCodecCtx,pCodec,NULL)<0){
qDebug() << "Could not open codec. " << endl;
return;
}
// 创建帧结构,此函数仅分配基本结构空间,图像数据空间需通过av_malloc分配 。
pFrame = av_frame_alloc();
pFrameRGB = av_frame_alloc();
// 创建动态内存,创建存储图像数据的空间
// av_image_get_buffer_size 获取一帧图像需要的大小
out_buffer = (unsigned char*)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_RGB32, pCodecCtx->width, pCodecCtx->height,1));
av_image_fill_arrays(pFrameRGB->data,pFrameRGB->linesize,out_buffer,
AV_PIX_FMT_RGB32, pCodecCtx->width,pCodecCtx->height, 1);
packet = (AVPacket*)av_malloc(sizeof(AVPacket));
// Output Info
qDebug() << "------------ File Information -------------" << endl;
// 此函数打印输入或输出的详细信息
av_dump_format(pFormatCtx, 0, filepath, 0);
qDebug() << "----------------" << endl;
// 初始化img_convert_ctx结构
img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height,pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_RGB32, SWS_BICUBIC, NULL, NULL, NULL);
// av_read_frame读取一帧未解码的数据
while(av_read_frame(pFormatCtx,packet)>=0){
// 如果是视频数据
if (packet->stream_index==videoindex){
// 解码一帧视频数据
ret = avcodec_decode_video2(pCodecCtx,pFrame, &got_picture, packet);
if(ret<0){
qDebug() << "Decode error" << endl;
return;
}
if(got_picture){
sws_scale(img_convert_ctx, (const unsigned char* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height,
pFrameRGB->data, pFrameRGB->linesize);
QImage img((uchar*)pFrameRGB->data[0],pCodecCtx->width,pCodecCtx->height, QImage::Format_RGB32);
ui->label->setPixmap(QPixmap::fromImage(img));
Delay(40);
}
}
av_free_packet(packet);
}
sws_freeContext(img_convert_ctx);
av_frame_free(&pFrameRGB);
av_frame_free(&pFrame);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx);
}
error missing -D__STDC_CONSTANT_MACROS / #define __STDC_CONSTANT_MACROS
D:\Documents\FFMpeg\dev\include\libavutil\common.h:205: error: 'UINT64_C' was not declared in this scope
if ((a+0x80000000u) & ~UINT64_C(0xFFFFFFFF)) return (int32_t)((a>>63) ^ 0x7FFFFFFF);
^
libavutil/common.h 顶部增加如下代码
#ifdef __cplusplus
#define __STDC_CONSTANT_MACROS
#ifdef _STDINT_H
#undef _STDINT_H
#endif
# include "stdint.h"
#endif
#ifndef INT64_C
#define INT64_C(c) (c ## LL)
#define UINT64_C(c) (c ## ULL)
#endif
参考资源:
https://www.cnblogs.com/WushiShengFei/p/10837264.html
https://blog.csdn.net/leixiaohua1020/article/details/8652605