【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);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/41648.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

01 Web基础与HTTP协议

1.1 Web 基础 本章将介绍 Web 基础知识&#xff0c;包括域名的概念、DNS 原理、静态网页和动态网页的相关知识。 1.1.1.域名概述 1.域名的概念 ip地址不易记忆 2.早期使用host文件解析域名 主机名重复主机维护困难 3.DNS 分布式层次式 4.域名空间结构 根域顶级域 组…

InstantStyle-Plus:风格转移与内容保留在文本到图像的生成

在之前的文章中已经和大家介绍过小红书在风格保持方面的优秀工作InstantID和InstantStyle,感兴趣的小伙伴可以点击下面&#x1f447;链接阅读&#xff5e; 小红书InstantID来了, 一张照片几秒钟就能生成个性化图片, 无缝衔接Stable Diffusion&#xff09; InstantID作者新作&…

国外使用代理IP的安全风险

1. 数据泄露 当使用代理IP时&#xff0c;用户的真实IP地址被隐藏&#xff0c;但仍然存在数据泄露的风险。如果代理服务器没有进行恰当的安全措施&#xff0c;用户的个人信息和访问记录可能会被黑客窃取或监控。 2. 恶意软件 在使用代理IP时&#xff0c;用户可能会在代理服务器…

关于 Mac 系统 .DS_store 文件的起源

原文&#xff1a;Arno - 2006.10.01 &#xff08;前排提醒&#xff1a;可以在 .gitignore 中添加 .DS_Store&#xff0c;否则 git 仓库会存储这个和项目无关的文件。&#xff09; 如果你是 Mac 用户&#xff0c;曾经将文件从 Mac 传输到 Windows&#xff0c;那么可能对 .DS_S…

c++ word转换为pdf

在windows系统下&#xff0c;使用QAxObject效果是最好的 转60多兆的文件速度还是可以的&#xff0c;不建议使用多线程&#xff0c;因为多线程会多次调用转换函数&#xff0c;导致程序一直运行&#xff0c;只有全部转换完成后&#xff0c;程序才能继续向下运行&#xff0c;但是c…

SketchUp + Enscape+ HTC Focus3 VR

1. 硬件: 设备连接 2. 软件: 安装steam steamVR Vive Business streaming 3. 操作: 双方登录steam 账号,然后带上头盔,用手柄在HTC Focus3 安装 串流软件,选择串流软件,在Enscape中选择 VR 模式即可 4.最终效果: SketchUp Enscape HTC Focus 3 VR 实时预览_哔哩哔哩_bi…

云微客短视频矩阵全域营销,更高效的获客引流方式!

在抖音这样一个拥有海量用户和内容的短视频平台上&#xff0c;单一账号往往难以覆盖我们的客户群体&#xff0c;甚至于每天发布四五条视频&#xff0c;所引发的流量也是微乎其微的。在竞争如此激烈的市场环境中&#xff0c;商家企业无不想方设法追求更高效的获客引流方式&#…

SQL Server 查询死锁以及解决死锁的基本知识(图文)

目录 1. 基本知识2. 查看和解锁被锁的表3. 查看和处理数据库堵塞 1. 基本知识 在 SQL Server 中&#xff0c;死锁是指两个或多个进程互相等待对方持有的资源&#xff0c;从而无法继续执行的现象 要解决死锁问题&#xff0c;首先需要识别并分析死锁的发生原因&#xff0c;然后…

Floyd判圈算法——环形链表(C++)

Floyd判圈算法(Floyd Cycle Detection Algorithm)&#xff0c;又称龟兔赛跑算法(Tortoise and Hare Algorithm)&#xff0c;是一个可以在有限状态机、迭代函数或者链表上判断是否存在环&#xff0c;求出该环的起点与长度的算法。 …

什么是断路器模式?Hystrix在其中扮演什么角色?

断路器模式&#xff08;Circuit Breaker Pattern&#xff09; 断路器模式是一种设计模式&#xff0c;它用于在分布式系统中防止级联失败的发生。类比于电路中的断路器&#xff0c;该模式的核心思想是当系统检测到一些调用或响应出现问题&#xff08;如超时、异常等&#xff09…

科研绘图系列:R语言箱线图(boxplot)

介绍 使用 ggplot2 包画箱线图通常使用 geom_boxplot() 函数。箱线图(Boxplot)是一种用于展示一组数据分布特征的图形,它能够提供以下信息: 中位数:箱线图中的中位线表示数据的中位数。四分位数:箱线图的箱子部分表示数据的四分位数范围,即25%和75%分位数,这可以展示数…

SQL面试题练习 —— 各用户最长的连续登录天数-可间断

目录 1 题目2 建表语句3 题解 1 题目 现有各用户的登录记录表t_login_events如下&#xff0c;表中每行数据表达的信息是一个用户何时登录了平台。现要求统计各用户最长的连续登录天数&#xff0c;间断一天也算作连续&#xff0c;例如&#xff1a;一个用户在1,3,5,6登录&#xf…

NVM 设置系统/终端默认(default)NODE 版本

NVM 设置系统/终端默认&#xff08;default&#xff09;NODE 版本 nvm alias default node版本查看当前 default 指向的 node 版本为 v16.17.1 nvm alias default 切换系统默认版本 查看当前 default 指向新版本

使用POI实现Excel文件的读取(超详细)

目录 一 导入poi相关的maven坐标 二 实现创建并且写入文件 2.1实现步骤 2.2实现代码 2.3效果展示 ​编辑 2.4注意 三 实现从Excel文件中读取数据 3.1实现步骤 3.2实现代码 3.3结果展示 一 导入poi相关的maven坐标 <!-- Apache poi --><dependency><gro…

【机器学习】机器学习与自然语言处理的融合应用与性能优化新探索

引言 自然语言处理&#xff08;NLP&#xff09;是计算机科学中的一个重要领域&#xff0c;旨在通过计算机对人类语言进行理解、生成和分析。随着深度学习和大数据技术的发展&#xff0c;机器学习在自然语言处理中的应用越来越广泛&#xff0c;从文本分类、情感分析到机器翻译和…

MySQL集群如何在主节点查询从节点的IP信息

在MySQL集群环境中&#xff0c;要查询从节点&#xff08;也称为复制从库&#xff09;的IP信息&#xff0c;你可以通过在主节点上执行相关的SQL查询来获取。这里提供了一些可能的方法&#xff1a; 方法一&#xff1a;SHOW SLAVE HOSTS命令&#xff08;适用于MySQL复制环境&…

1990-2021年297个地级市RD内部经费支出数据

地级市内部经费支出数据为研究者提供了了解地方政府在科研活动上的投入情况的重要视角。以下是对297个地级市R&D内部经费支出数据的介绍&#xff1a; 数据简介 定义&#xff1a;地级市内部经费支出是指地级市政府在一定时期内用于科研活动的经费支出。用途&#xff1a;这…

C语言 | Leetcode C语言题解之第217题存在重复元素

题目&#xff1a; 题解&#xff1a; struct hashTable {int key;UT_hash_handle hh; };bool containsDuplicate(int* nums, int numsSize) {struct hashTable* set NULL;for (int i 0; i < numsSize; i) {struct hashTable* tmp;HASH_FIND_INT(set, nums i, tmp);if (tm…

SQL 汇总各个部门当前员工的title类型的分配数目

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 描述 有一个部门表…

Sharding-JDBC

一、概念&#xff1a; Sharding-JDBC是一个在客户端的分库分表工具。它是一个轻量级Java框架&#xff0c;在Java的JDBC层提供的额外服务。 ShardingSphere提供标准化的数据分片、分布式事务和数据治理功能。 二、架构图&#xff1a; ShardingRuleConfiguration 可以包含多个 T…