当前位置: 首页 > 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…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...