当前位置: 首页 > news >正文

【FFMPEG基础(一)】解码源码

学习分享

  • main函数
  • decodetorgb32.h 文件
  • decodetorgb32 .cpp文件

main函数

#include <QApplication>
#include "decodetorgb32.h"
int main(int argc, char *argv[])
{QApplication a(argc, argv);DecodeToRGB32 toRGB32;int res=toRGB32.openVideo("../fileIn/Warcraft3_End.avi");if(res ==0){if(toRGB32.findStream() ==0){if(toRGB32.openDecoder()==0){toRGB32.decodeRGB();}}}return a.exec();
}

decodetorgb32.h 文件

#ifndef DECODETORGB32_H
#define DECODETORGB32_H
#include <QString>
#include <QDebug>
#include <QImage>
#include <stdio.h>
extern "C"
{#include "libavcodec/avcodec.h"             //编解码库#include "libavdevice/avdevice.h"           //输入给输出设备库,读取摄像头#include "libavfilter/avfilter.h"           //音视频滤镜库;进行音视频处理和编辑#include "libavformat/avformat.h"           //文件格式和协议库#include "libavutil/avutil.h"               //音视频处理#include "libswresample/swresample.h"       //音频重采样#include "libswscale/swscale.h"             //图像进行格式转换}class DecodeToRGB32
{
public:DecodeToRGB32();/** 1、注册组件 2、打开视频* @brief openVideo* @param filename* @return  0-success  else error*/int openVideo(QString filename);/** 3、查找流媒体数据  4、查找视频流* @brief findStream* @return 0-查找到视频流数据 1-查找流媒体数据  <0无流媒体数据*/int findStream();/** 5、查找解码器  6、打开解码器* @brief openDecoder* @return*/int openDecoder();/** 读取pkt* @brief decodeRGB*/void decodeRGB();
private:AVFormatContext* pFormatContext;    //封装格式上下文结构体int video_index;                    //视频流所在的下标AVCodecContext *pCodecContext;      //编解码器上下文结构体AVCodec*deocder;                    //解码器AVPacket * pkt;                     //码流数据AVFrame * picture,* pictureRGB,*pictureYUV;//1:不纯净的携带脏数据的像素数据,2:存储转置后的纯净的RGB像素数据 ,3:存储转置后的纯净的YUV像素数据};#endif // DECODETORGB32_H

decodetorgb32 .cpp文件

#include "decodetorgb32.h"DecodeToRGB32::DecodeToRGB32()
{}
//1、注册组件 2、打开视频
int DecodeToRGB32::openVideo(QString filename)
{av_register_all();//注册所用组件//全局结构体开空间this->pFormatContext=avformat_alloc_context();//打开输入视频文件int res=avformat_open_input(&this->pFormatContext,filename.toUtf8(),nullptr,nullptr);if(res!=0){qDebug()<<"open_input fail"<<res;//不等于0,文件打开失败}return res;
}
//3、查找流媒体数据  4、查找视频流
int DecodeToRGB32::findStream()
{//1.查找流媒体数据int res= avformat_find_stream_info(this->pFormatContext,nullptr);if(res<0){qDebug()<<"find_stream_info fail"<<res;//小于0查找失败return res;}//2.查看是否有视频流for (int i=0;i<this->pFormatContext->nb_streams;i++)//输入视频的AVStream的个数{//                                streams:输入视频的AVStream数组/codec:该流对应的AVCodecContext/编解码器类型if(AVMEDIA_TYPE_VIDEO==this->pFormatContext->streams [i]->codec->codec_type){this->video_index=i;return 0;}}return res;
}
//查找解码器,打开解码器
int DecodeToRGB32::openDecoder()
{int res=-1;//编解码器上下文结构体this->pCodecContext=this->pFormatContext->streams[this->video_index]->codec;//编解码器的AVCodecthis->deocder= avcodec_find_decoder(this->pCodecContext->codec_id);//查找解码器if(nullptr==this->deocder){qDebug()<<"find_decoder fail"<<res;return 1;}//打开解码器res=avcodec_open2(this->pCodecContext,this->deocder,nullptr);if(res!=0){qDebug()<<"find_decoder fail"<<res;}return res;//0 找到了并打开   <0未打开解码器
}void DecodeToRGB32::decodeRGB()
{//7、准备数据this->pkt =(AVPacket*)malloc(sizeof(AVPacket));//存储一帧压缩编码数据int size =this->pCodecContext->width*this->pCodecContext->height;av_new_packet(this->pkt,size);//初始化像素数据this->picture  =av_frame_alloc();//创建一个存储解码的像素数结构体this->picture->width=this->pCodecContext->width;this->picture->height=this->pCodecContext->height;this->picture->format=this->pCodecContext->pix_fmt;this->pictureRGB=av_frame_alloc();this->pictureRGB->width=this->pCodecContext->width;this->pictureRGB->height=this->pCodecContext->height;this->pictureRGB->format=this->pCodecContext->pix_fmt;this->pictureYUV=av_frame_alloc();this->pictureYUV->width=this->pCodecContext->width;this->pictureYUV->height=this->pCodecContext->height;this->pictureYUV->format=this->pCodecContext->pix_fmt;//计算一帧RGB32的像素大小int imgByte=avpicture_get_size(AV_PIX_FMT_RGB32,this->pCodecContext->width,this->pCodecContext->height);//动态开空间uint8_t*buffer=(uint8_t*)malloc(imgByte*sizeof(uint8_t));//图片的数据填充avpicture_fill((AVPicture*)this->pictureRGB,buffer,AV_PIX_FMT_RGB32,this->pCodecContext->width,this->pCodecContext->height);//制定转置的规则SwsContext*swContext=sws_getContext(this->pCodecContext->width,this->pCodecContext->height,this->pCodecContext->pix_fmt,this->pCodecContext->width,this->pCodecContext->height,AV_PIX_FMT_RGB32,SWS_BICUBIC,nullptr,nullptr,nullptr);/**准备YUV数据**********************///计算一帧YUV420P的像素大小int imgByteYUV=avpicture_get_size(AV_PIX_FMT_YUV420P,this->pCodecContext->width,this->pCodecContext->height);//动态开空间uint8_t*bufferYUV=(uint8_t*)malloc(imgByte*sizeof(uint8_t));//图片的数据填充avpicture_fill((AVPicture*)this->pictureYUV,bufferYUV,AV_PIX_FMT_YUV420P,this->pCodecContext->width,this->pCodecContext->height);//制定转置的规则SwsContext*swContextYUV=sws_getContext(this->pCodecContext->width,this->pCodecContext->height,this->pCodecContext->pix_fmt,this->pCodecContext->width,this->pCodecContext->height,AV_PIX_FMT_YUV420P,SWS_BICUBIC,nullptr,nullptr,nullptr);int num=0;FILE * pyuv=fopen("../fileOut/save.yuv","wb+");//二进制方式写入char path[256]={0};//8、读取码流数据、解封装    获取一帧压缩的码流数据while(av_read_frame(this->pFormatContext,this->pkt)==0)//0成功{//判断码流数据类型是视频流if(pkt->stream_index==this->video_index){int got_num =-1;//参数一:编解码器上下文结构体  二;AVFrame* 像素数据     三:int*标志位  四:一帧压缩码流数据avcodec_decode_video2(this->pCodecContext,this->picture,&got_num,this->pkt);if(got_num !=0){qDebug()<<"解码成功:"<<num;//剔除无效数据,获取纯净的RGB32数据/*** parmam1:转置规则* srcSlice 数据* srcStride 每一行的数据* srcSliceY 从第几行开始扫描* srcSliceH 图片高度* dst       目标数据* dstStrde  一行的宽度* @brief sws_scale*///存储图片 -播放sws_scale(swContext,picture->data,picture->linesize,0,this->picture->height,this->pictureRGB->data,this->pictureRGB->linesize);//用于存储 size更小sws_scale(swContextYUV,picture->data,picture->linesize,0,this->picture->height,this->pictureYUV->data,this->pictureYUV->linesize);fwrite(this->pictureYUV->data[0],this->pCodecContext->width*this->pCodecContext->height,1,pyuv);//  1 -Yfwrite(this->pictureYUV->data[1],this->pCodecContext->width*this->pCodecContext->height/4,1,pyuv);//  1/4 -Ufwrite(this->pictureYUV->data[2],this->pCodecContext->width*this->pCodecContext->height/4,1,pyuv);//  1/4 -V//pictureRGB 转储为QImageQImage img((uchar*)buffer,this->pictureRGB->width,this->pictureRGB->height,QImage::Format_RGB32);sprintf(path,"../fileOut/image%d.png",num);img.save(path);num++;if(num>5) break;}}}qDebug()<<num;fclose(pyuv);
}

相关文章:

【FFMPEG基础(一)】解码源码

学习分享 main函数decodetorgb32.h 文件decodetorgb32 .cpp文件 main函数 #include <QApplication> #include "decodetorgb32.h" int main(int argc, char *argv[]) {QApplication a(argc, argv);DecodeToRGB32 toRGB32;int restoRGB32.openVideo("../fi…...

第二证券股市资讯:深夜!突然暴涨75%!

一则重磅收买引发医药圈轰动。 北京时间7月8日晚间&#xff0c;美股开盘后&#xff0c;美国生物制药公司Morphic股价一度暴升超75%。音讯面上&#xff0c;生物医药巨子礼来公司官宣&#xff0c;将以57美元/股的价格现金收买Morphic&#xff0c;较上星期五的收盘价溢价79%&…...

flutter 使用wechat_assets_picker的权限检测

https://pub.dev/packages/wechat_assets_picker AssetPicker.pickAssets之前进行权限检查 pickImages() async {try {if (PermissionState.authorized ! await AssetPicker.permissionCheck()) {PermissionUtil.showAllPermissions(Permission.storage, 1);return;}final Lis…...

Mojo入门案例教程(上手篇)

以下是 Mojo 编程语言入门案例教程&#xff0c;内容包括 Mojo 的基本概念、变量、控制结构、函数等方面&#xff1a; Mojo 的基本概念 1.什么是 Mojo&#xff1f;&#xff1a;Mojo 是一种函数式编程语言&#xff0c;用于开发小型应用程序、脚本和工具。 2.Mojo 的特点&#x…...

如何在window执行mkfile

1、Windows cmd中出现错误&#xff1a;“‘make‘ 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。”的解决方法_windows_是板栗啊-GitCode 开源社区 2、安装cmder&#xff0c;再通过包管理工具下载make...

Nginx 是一个非常流行的 Web 服务器和反向代理服务器

Nginx 是一个非常流行的 Web 服务器和反向代理服务器&#xff0c;以其高性能、稳定性、丰富的功能集和低资源消耗而闻名。下面是一个简化的 Nginx 使用教程&#xff0c;包括基本的安装、配置和一些常见用途。 安装 Nginx 在 Ubuntu/Debian 上安装&#xff1a; sudo apt upda…...

mysql怎么调整缓冲区大小

MySQL中调整缓冲区大小是数据库性能优化的重要一环。缓冲区大小直接影响了数据库的读写性能和响应速度。以下是一些常见的MySQL缓冲区及其调整方法&#xff1a; 一、InnoDB缓冲池&#xff08;InnoDB Buffer Pool&#xff09; InnoDB缓冲池是InnoDB存储引擎用来缓存表数据和索…...

计算机组成原理学习笔记(一)

计算机组成原理 [类型:: [[计算机基础课程]] ] [来源:: [[B站]] ] [主讲人:: [[咸鱼学长]] ] [评价:: ] [知识点:: [[系统软件]] & [[应用软件]] ] [简单解释:: 管理计算机系统的软件&#xff1b; 按照任务需要编写的程序 ] [问题:: ] [知识点:: [[机器字长]] ] [简单…...

Vue3 对跳转 同一路由传入不同参数的页面分别进行缓存

1&#xff1a;使用场景 从列表页跳转至不同的详情页面&#xff0c;对这些详情页面分别进行缓存 2&#xff1a;核心代码 2.1: 配置路由文件 在路由文件里对需要进行缓存的路由对象添加meta 属性 // 需要缓存的详情页面路由 { name: detail, path: /myRouter/detail…...

LinearLayout的测量流程

在日常开发中我们常常使用LinearLayout作为布局Group&#xff0c;本文从其源码实现出发分析测量流程。大家可以带着问题进入下面的分析流程&#xff0c;看看是否能找到答案。 垂直测量 View的测量入口方法是onmeasure方法。LinearLayout的onMeasure方法根据其方向而做不同的处…...

数据无忧:Ubuntu 系统迁移备份全指南

唠唠闲话 最近电脑出现了一些故障&#xff0c;送修期间&#xff0c;不得不在实验室的台式机上重装系统&#xff0c;配环境的过程花费了不少时间。为避免未来处理类似事情时耗费时间&#xff0c;特此整理一些备份策略。 先做以下准备&#xff1a; U盘启动盘&#xff0c;参考 …...

中国IDC圈探访北京•光子1号金融算力中心

今天&#xff0c;“AI”、“大模型”是最炙手可热的话题&#xff0c;全球有海量人群在工作生活中使用大模型&#xff0c;大模型产品涉及多模态&#xff0c;应用范围已涵盖电商、传媒、金融、短视频、制造等众多行业。 而回看2003年的互联网记忆&#xff0c; “上网”“在线”是…...

[Unity入门01] Unity基本操作

参考的傅老师的教程学了一下Unity的基础操作&#xff1a; [傅老師/Unity教學] Unity3D基礎入門 [華梵大學] 遊戲引擎應用基礎(Unity版本) Class#01 移动&#xff1a;鼠标中键旋转&#xff1a;鼠标右键放大&#xff1a;鼠标滚轮飞行模式&#xff1a;右键WASDQEFocus模式&…...

vivado DELAY_VALUE_XPHY、DIFF_TERM

延迟_值_XPHY PORT对象上的DELAY_VALUE_XPHY属性指定要添加的延迟量 Versal XPHY逻辑接口的输入或输出路径。在的早期阶段 opt_design在重新生成高级I/O向导IP时 DELAY_VALUE_XPHY值将从PORT复制到的XPHY实例上 输入或输出路径。Vivado设计套件中存在DRCs&#xff0c;以确保 DE…...

C++语言相关的常见面试题目(三)

1. List底层实现原理 省流&#xff1a; list底层实现了一个双向循环链表。 每个元素&#xff08;或节点&#xff09;包含三个部分&#xff1a;数据域(_M_Storage)、前驱指针(_M_prev)、后继指针(_M_next)。 数据域&#xff1a;存储实际数据。 前驱指针&#xff1a;指向链表中…...

代码随想录-Day53

739. 每日温度 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不会升高&#xff0c;请在该位置用 0 来代替。 示例 1: …...

Android 如何通过代码实时设置EditTextView光标

背景&#xff1a;换肤框架下&#xff0c;QA进行深色浅色切换说输入框光标颜色没有改变&#xff0c;转UI结果UI说需要修改&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 本来有方法可以设置&#xff0c;但是 设置后未生效。重新进入该页面才生效&#xff01;&a…...

202488读书笔记|《365日创意文案》——无聊的 到底是这世间, 还是自己?懂得忘却的人才能前进

202488读书笔记|《365日创意文案》——无聊的 到底是这世间&#xff0c; 还是自己&#xff1f;懂得忘却的人才能前进 1月2月3月4月5月6月7月8月9月10月11月12月 《365日创意文案》WRITES PUBLISHING&#xff0c;一些日常&#xff0c;是烟火&#xff0c;也是幸福的印记。 当下也…...

iperf3: error - unable to connect to server: No route to host

1.确认iperf3版本是否统一。 2.确认防火墙是否关闭。 关闭防火墙 : systemctl stop firewalld 查看防火墙状态: systemctl status firewalld 3.重新建起链接...

正则表达式中的贪心匹配

在正则表达式中&#xff0c;&#xff1f;既可以表示数量&#xff0c;0次或1次&#xff0c;等效于 {0&#xff0c;1}&#xff0c;也可以跟在其它数量限定符之后&#xff0c;表示非贪心匹配&#xff0c;即匹配时匹配搜索到的尽可能短的字符串。 下面来看一个例子&#xff1a; T…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !

我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...

Matlab实现任意伪彩色图像可视化显示

Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中&#xff0c;如何展示好看的实验结果图像非常重要&#xff01;&#xff01;&#xff01; 1、灰度原始图像 灰度图像每个像素点只有一个数值&#xff0c;代表该点的​​亮度&#xff08;或…...

Java 与 MySQL 性能优化:MySQL 慢 SQL 诊断与分析方法详解

文章目录 一、开启慢查询日志&#xff0c;定位耗时SQL1.1 查看慢查询日志是否开启1.2 临时开启慢查询日志1.3 永久开启慢查询日志1.4 分析慢查询日志 二、使用EXPLAIN分析SQL执行计划2.1 EXPLAIN的基本使用2.2 EXPLAIN分析案例2.3 根据EXPLAIN结果优化SQL 三、使用SHOW PROFILE…...