来自:http://blog.csdn.net/x348722662/article/details/53445136
本文对在QT中实时显示yuv数据提供一个解决方案,再次特别非常感谢http://blog.yundiantech.com/中的博文,也是借鉴其中的播放YUV文件的demo实现实时播放yuv视频数据,废话不多说,就直接介绍显示效果最好的方法吧
- qt中利用mmfpeg将yuv转RGB32
- qt中将rbg显示到label上
qt中利用mmfpeg将yuv转RGB32
因为在QT中是无法直接显示yuv数据,所以我们必须把yuv数据转换成RGB32通过QImage来显示到控件中,具体的yuv和rgb的基本介绍就不在此给大家做介绍,需要知道原理的自行百度,如果想自己通过写转换代码来实现,也是可以的,只不过转换出来的效果不是太理想,特别是在纯白的背景时候,会有纯红,纯绿,纯蓝的颜色出现,导致整个颜色的偏差,所以我们直接采用mmfpeg中的yuv转rgb的方法,优化和效率都不错。
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libavdevice/avdevice.h"
}
uint8_t *yuvBuffer;
AVFrame *pFrame ;
AVFrame *pFrameRGB;
uint8_t * rgbBuffer;
SwsContext *img_convert_ctx;
void InitPlay(int width,int height)
{
int yuvSize = width * height * 3 /2;
yuvBuffer = (uint8_t *)malloc(yuvSize);
pFrame = av_frame_alloc();
pFrameRGB = av_frame_alloc();
int numBytes = avpicture_get_size(PIX_FMT_RGB32, width,height);
rgbBuffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));
avpicture_fill((AVPicture *) pFrameRGB, rgbBuffer, PIX_FMT_RGB32,width, height);
img_convert_ctx = sws_getContext(width, height, AV_PIX_FMT_YUV420P, width, height, PIX_FMT_RGB32, SWS_BICUBIC, NULL, NULL, NULL);
}
void wb_yuv(void* str,int len)
{
avpicture_fill((AVPicture *) pFrame, (uint8_t *)str, AV_PIX_FMT_YUV420P, width, height);
sws_scale(img_convert_ctx,
(uint8_t const * const *) pFrame->data,
pFrame->linesize, 0, height, pFrameRGB->data,
pFrameRGB->linesize);
QImage tmpImg((uchar *)rgbBuffer,mWidth,mHeight,QImage::Format_RGB32);
QImage image = tmpImg.copy();
emit sig_GetOneFrame(image);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
qt中将RGB32显示到label上
继承了一个QLbel的类,重写paintEvent事件,将RBG绘制到界面中
void DecLabel::slotGetOneFrame(QImage img)
{
wb_Image = img;
update();
}
void DecLabel::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
if (wb_Image.size().width() <= 0) return;
QImage img = wb_Image.scaled(this->size,Qt::IgnoreAspectRatio);
int x = this->width() - img.width();
int y = this->height() - img.height();
painter.drawImage(QPoint(x,y),img);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
小结:实际应用中,因为我们有自己的解码库,将实时的H.264数据解码成YUV数据,但需要自己做显示,就借鉴FFMPEG中YUV转RGB32方法,实现之后效果还不错。