一、官网下载ffmpeg库
1.点击Windows图标下面的第一个库连接 官网地址:https://ffmpeg.org/download.html 库地址:https://www.gyan.dev/ffmpeg/builds/ 2.选择发行版本库,这里我选择的是共享库5.0 3.解压后如下图所示,bin文件夹带有官方发行版本运行库xx.dll,lib文件夹带有我们所使用的开发库
二、建立QT工程
1.你可以和我一样,亦可以自行选择工程 2.pro工程套件配置,编译器选择64位的编译器,当然你也可以选择32位的编译器MinGw 3.pro文件链接ffmpeg库,注意,库有64位的,也有32位的,对应自己QT的MinGw的位数 4.包含头文件,由于ffmpeg库是由c语言编写,所以头文件声明为 extern "c”
三、编程
1.头文件
class MyTest : public QMainWindow
{
Q_OBJECT
public:
MyTest(QWidget *parent = nullptr);
~MyTest();
void readDir(QString _dirname);
void readFile(QString file_path);
void readUiArg();
void setUiArg();
void yuvToRgb(void* str,AVPixelFormat yuv_fmt,uint32_t str_w, uint32_t str_h);
void showImag(QString file_path);
protected:
void paintEvent(QPaintEvent *event);
private slots:
void slotGetOneFrame(QImage img);
void slotBtnClicked();
void on_listWidget_file_itemDoubleClicked(QListWidgetItem *item);
void on_comboBox_wh_currentIndexChanged(const QString &arg1);
signals:
void sig_GetOneFrame(QImage img);
private:
Ui::MyTest *ui;
QVector <QString>filename;
QString dirname;
QImage rgbImage,displayImage;
QByteArray str_date;
uint32_t file_size;
uint32_t yuv_w,yuv_h,yuv_size;
uint32_t rgb_w,rgb_h,rgb_size;
AVPixelFormat cur_yuv_fmt;
uint8_t *yuvBuffer;
AVFrame *pFrame ;
AVFrame *pFrameRGB;
uint8_t * rgbBuffer;
SwsContext *img_convert_ctx;
QString cur_img_path;
int n_count;
int index;
};
2.重要方法函数 yuv转rgb
void MyTest::yuvToRgb(void *str,AVPixelFormat yuv_fmt, uint32_t str_w, uint32_t str_h)
{
rgb_w = str_w;
rgb_h = str_h;
yuv_size = str_w * str_h * 3 /2;
yuvBuffer = (uint8_t *)malloc(yuv_size);
pFrame = av_frame_alloc();
pFrameRGB = av_frame_alloc();
rgb_size =av_image_get_buffer_size(AV_PIX_FMT_RGB32, rgb_w, rgb_h, 1);
rgbBuffer = (uint8_t *) av_malloc(rgb_size * sizeof(uint8_t));
av_image_fill_arrays(pFrameRGB->data, pFrameRGB->linesize, rgbBuffer, AV_PIX_FMT_RGB32, rgb_w, rgb_h,1);
img_convert_ctx = sws_getContext(str_w, str_h, yuv_fmt, rgb_w, rgb_h, AV_PIX_FMT_RGB32, SWS_BICUBIC, NULL, NULL, NULL);
av_image_fill_arrays(pFrame->data,pFrame->linesize,(uint8_t *)str, yuv_fmt, str_w,str_h,1);
sws_scale(img_convert_ctx,(uint8_t const * const *) pFrame->data,\
pFrame->linesize, 0, str_h, pFrameRGB->data, pFrameRGB->linesize);
for(int i=0;i<10000;i++)
for(int i=0;i<1000;i++);
QImage tmpImg((uchar *)rgbBuffer,rgb_w,rgb_h,QImage::Format_RGB32);
rgbImage = tmpImg.copy();
}
3.事件重绘方法函数
void MyTest::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
if (rgbImage.size().width() <= 0) return;
QImage img = rgbImage.scaled(ui->widget_video->size(),Qt::KeepAspectRatio);
int x = ui->widget_video->width() - img.width();
int y = ui->widget_video->height() - img.height();
x /= 2;
y /= 2;
painter.drawImage(QPoint(x,y),img);
}
4.递归加载文件
void MyTest::readDir(QString _dirname)
{
QDir mydir(_dirname);
QStringList filelist=mydir.entryList();
for(int i=0;i<filelist.size();i++)
{
QString path=QString("%1/%2").arg(_dirname).arg(filelist.at(i));
if(filelist.at(i)=="."||filelist.at(i)=="..")
continue;
QFileInfo myinfo(path);
if(myinfo.isDir())
{
readDir(path);
}
if(myinfo.isFile())
{
if(filelist.at(i).contains(".yuv"))
{
ui->listWidget_file->addItem(filelist.at(i));
filename.push_back(path);
}
}
}
}
四、UI界面设计
1.ui界面
五、运行效果
1.选择图片格式及分辨率,我这里是YUV420 2592x1944,这些yuv图片是我用V4L2编程代码从硬件里面保存下来的。 2.双击yuv19.yuv
3.双击yuv20.yuv
六、结束语
1.由于自己从事硬件相关工作,需要查看yuv420格式的图片,从百度拿的app看yuv比较麻烦,所以自己就写了一个,百度的ffmpeg方法都是比较老的且有许多版本造成的问题,我这里是用最新的库编写的。
|