海思3519 qt ffmpeg 软解码播放avi
在海思3519上基于qt采用ffmpeg对avi进行解码显示,其中ffmpeg的配置,qt的配置在前文中已经说明,在此不再赘述。
解码
解码在单独的线程中进行,具体的代码如下:
void VideoPlayer::run()
{
AVFormatContext *fmt_ctx = NULL;
AVCodecContext *dec_ctx = NULL;
AVFrame *pf = av_frame_alloc();
AVFrame *pfc = av_frame_alloc();
int video_stream_index;
int width, height;
av_register_all();
video_stream_index = getStream(&fmt_ctx, &dec_ctx, "./source_file/test.avi");
decoder(&fmt_ctx, &dec_ctx, video_stream_index, pf, pfc, &width, &height);
}
int VideoPlayer::decoder(AVFormatContext** fmt_ctx, AVCodecContext** dec_ctx,
int video_stream_index, AVFrame *pFrame, AVFrame *pFrameColor, int* width, int* height)
{
AVPacket packet;
int i = 0;
int frameFinished;
uint8_t *buffer;
int numBytes;
char filename[32];
numBytes = avpicture_get_size(AV_PIX_FMT_RGB24, (*dec_ctx)->width, (*dec_ctx)->height);
buffer = (uint8_t*)av_malloc(numBytes);
avpicture_fill((AVPicture *)pFrameColor, buffer, AV_PIX_FMT_RGB24, (*dec_ctx)->width, (*dec_ctx)->height);
while (av_read_frame(*fmt_ctx, &packet) >= 0) {
if (packet.stream_index == video_stream_index) {
avcodec_decode_video2(*dec_ctx, pFrame, &frameFinished, &packet);
if (frameFinished)
{
struct SwsContext *img_convert_ctx = NULL;
img_convert_ctx = sws_getCachedContext(img_convert_ctx, (*dec_ctx)->width,
(*dec_ctx)->height, (*dec_ctx)->pix_fmt,
(*dec_ctx)->width, (*dec_ctx)->height,
AV_PIX_FMT_RGB24, SWS_BICUBIC,
NULL, NULL, NULL);
if (!img_convert_ctx) {
fprintf(stderr, "Cannot initialize sws conversion context\n");
exit(1);
}
sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data,
pFrame->linesize, 0, (*dec_ctx)->height, pFrameColor->data,
pFrameColor->linesize);
QImage tmpImg((uchar *)buffer,(*dec_ctx)->width,(*dec_ctx)->height,QImage::Format_RGB888);
QImage image = tmpImg.copy();
emit sig_GetOneFrame(image);
}
}
av_free_packet(&packet);
}
printf("finished");
av_free(buffer);
av_free(pFrameColor);
av_free(pFrame);
avcodec_close(*dec_ctx);
avformat_close_input(fmt_ctx);
}
int VideoPlayer::getStream(AVFormatContext **fmt_ctx, AVCodecContext **dec_ctx, char* file_name)
{
int video_stream_index = -1;
int ret;
bool decoder_init = false;
if ((ret = avformat_open_input(fmt_ctx, file_name, NULL, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "fail to open input file.\n");
return ret;
}
if ((ret = avformat_find_stream_info(*fmt_ctx, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "fail to find stream information.\n");
avformat_close_input(fmt_ctx);
return ret;
}
for (int i = 0; i < (*fmt_ctx)->nb_streams; i++) {
if ((*fmt_ctx)->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
video_stream_index = i;
if (!decoder_init) {
*dec_ctx = (*fmt_ctx)->streams[i]->codec;
AVCodec *cod = avcodec_find_decoder((*dec_ctx)->codec_id);
if (!cod) {
av_log(NULL, AV_LOG_ERROR, "fail to find decoder.\n");
avformat_close_input(fmt_ctx);
return 1;
}
if (avcodec_open2(*dec_ctx, cod, NULL) != 0) {
av_log(NULL, AV_LOG_ERROR, "fail to open codecer.\n");
avformat_close_input(fmt_ctx);
return 2;
}
decoder_init = true;
}
}
return 0;
}
return video_stream_index;
}
解码后将数据转换成RGB并进一步转换成QImage,每解码一帧数据后发送一个信号用于更新图像显示
QImage tmpImg((uchar *)buffer,(*dec_ctx)->width,(*dec_ctx)->height,QImage::Format_RGB888);
QImage image = tmpImg.copy();
emit sig_GetOneFrame(image);
显示
具体代码如下:
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setBrush(Qt::black);
painter.drawRect(0, 0, this->width(), this->height()); //先画成黑色
if (mImage.size().width() <= 0) return;
QImage img = mImage.scaled(this->size(),Qt::KeepAspectRatio);
int x = this->width() - img.width();
int y = this->height() - img.height();
x /= 2;
y /= 2;
painter.drawImage(QPoint(x,y),img); //画出图像
}
void MainWindow::slotGetOneFrame(QImage img)
{
mImage = img;
update();
}
总结:
编译后能够在板子上成功运行,但是显示比较缓慢,这块具体的原因没有进一步分析,因为后来才用了硬解码的方式,所以放弃了深入研究,参考代码获取
海思3519 qt ffmpeg 软解码播放avi的更多相关文章
- 海思3559A QT 5.12移植(带webengine 和 opengl es)
海思SDK版本:Hi3559AV100_SDK_V2.0.1.0 编译器版本:aarch64-himix100-linux-gcc 6.3.0(这个版本有点小问题,使用前需要先清除本地化设置) $ e ...
- 海思3519A 移植ffmpeg
文件下载 下载x264 git clone git://git.videolan.org/x264.git 下载ffmpeg git clone git://source.ffmpeg.org/ffm ...
- Qt + FFmpeg 本地音频播放器
http://pan.baidu.com/s/1hqoYXrI
- FFmpeg开发笔记(十):ffmpeg在ubuntu上的交叉编译移植到海思HI35xx平台
FFmpeg和SDL开发专栏(点击传送门) 上一篇:<FFmpeg开发笔记(九):ffmpeg解码rtsp流并使用SDL同步播放>下一篇:敬请期待 前言 将ffmpeg移植到海思H ...
- OpenCV开发笔记(七十四):OpenCV3.4.1+ffmpeg3.4.8交叉编译移植到海思平台Hi35xx平台
前言 移植opencv到海思平台,opencv支持对视频进行解码,需要对应的ffmpeg支持. Ffmpeg的移植 Ffmpeg的移植请参考之前的文章:<FFmpeg开发笔记(十): ...
- (转)海思平台HI35XX系列内存设置
海思平台的内存分为两部分,一部分给系统使用,另外的一部分给多媒体使用.可以通过cat /proc/meminfo查看系统内存和cat /proc/media-mem 查看多媒体内存使用情况. /pro ...
- 海思3519A 移植 Qt 5.5.1
源码下载 网址:qt-everywhere-opensource-src-5.5.1.tar.gz 配置生成MakeFile 文件 解压源码包,在源码包路径下生成配置 MakeFile : ./con ...
- 使用C#+FFmpeg+DirectX+dxva2硬件解码播放h264流
本文门槛较高,因此行文看起来会乱一些,如果你看到某处能会心一笑请马上联系我开始摆龙门阵 如果你跟随这篇文章实现了播放器,那你会得到一个高效率,低cpu占用(单路720p视频解码播放占用1%左右cpu) ...
- 海思HI35xx平台软件开发快速入门之H264解码实例学习
ref :https://blog.csdn.net/wytzsjzly/article/details/82500277 前言 H264视频编码技术诞生于2003年,至今已有十余载,技术相当成熟 ...
随机推荐
- WebSocket协议-原理篇
本篇文章主要讲述以下几点: WebSocket的原理与机制 WebSocket与Socket.io WebSocket兼容性 WebSocket的原理与机制 WebSocket协议分为两部分:握手和数 ...
- leetcode622. 设计循环队列
设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环.它也被称为“环形缓冲器”. 循环队列的一个好处是我们可以利用这个队列 ...
- 忍者钩爪 ( ninja) 题解———2019.10.19
可以到这里测..嘿嘿嘿 题目: [问题 描述 ] 小 Q 是一名酷爱钩爪的忍者, 最喜欢飞檐走壁的感觉, 有一天小 Q 发现一个练习使用钩 爪的好地方,决定在这里大显身手. 场景的天花板可以被描述为一 ...
- 关于RAMOS所用的操作系统
关于RAMOS所用的操作系统 RAMOS所用的操作系统,XP就不用说了,精简版最小的600MB到1.5GB的都有.现代意义上的WIN7/8/10 RAMOS一般选用精简版操作系统,节约内存的同时,还能 ...
- Linux性能优化实战学习笔记:第十六讲
一.free数据的来源 1.碰到看不明白的指标时该怎么办吗? 不懂就去查手册.用 man 命令查询 free 的文档.就可以找到对应指标的详细说明.比如,我们执行 man fre... 2.free数 ...
- Linux性能优化实战学习笔记:第四十二讲
一.上节回顾 上一节,我们学习了 NAT 的原理,明白了如何在 Linux 中管理 NAT 规则.先来简单复习一下. NAT 技术能够重写 IP 数据包的源 IP 或目的 IP,所以普遍用来解决公网 ...
- Linux性能优化实战学习笔记:第五十七讲
一.上节回顾 上一节,我带你一起梳理了常见的性能优化思路,先简单回顾一下.我们可以从系统和应用程序两个角度,来进行性能优化. 从系统的角度来说,主要是对 CPU.内存.网络.磁盘 I/O 以及内核软件 ...
- [LeetCode] 321. Create Maximum Number 创建最大数
Given two arrays of length m and n with digits 0-9 representing two numbers. Create the maximum numb ...
- [LeetCode] 289. Game of Life 生命游戏
According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellul ...
- [LeetCode] 98. Validate Binary Search Tree 验证二叉搜索树
Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...