qt+ffmpeg 实现音视频播放(三)之视频播放

一、视频播放流程

(PS:视频的播放流程跟音频的及其相似!!)

1、打开视频文件

通过 avformat_open_input() 打开媒体文件并分配和初始化

AVFormatContext 结构体。

函数原型如下:

int avformat_open_input(AVFormatContext **ps, const char *url,

AVInputFormat *fmt, AVDictionary **options);

参数说明:

- `ps`:指向 `AVFormatContext` 结构体指针的指针,用于存储打

开的媒体文件的信息。

- `url`:要打开的媒体文件的 URL 或文件路径。

- `fmt`:指定输入格式,通常可以设置为 `NULL`,由 FFmpeg 根

据文件内容自动检测。

- `options`:附加选项,可以传入一些额外的选项参数。

2、查找输入流信息

调用  avformat_find_stream_info()  函数将会读取媒体文件中的

帧,解析它们的头部,

并填充 AVFormatContext 中的流信息,通过访问

AVFormatContext 的 streams 字段来获取每个流的详细信息。

函数原型如下:
int avformat_find_stream_info(AVFormatContext *ic,

AVDictionary **options);

参数说明:

- `ic`:指向已打开媒体文件的 `AVFormatContext` 结构体的指

针。

- `options`:指向包含附加选项的 `AVDictionary` 指针。

3、查找流索引

使用 av_find_best_stream() 从媒体文件中找到最佳的流索引

函数原型如下:

int av_find_best_stream(AVFormatContext *ic, enum

AVMediaType type, int wanted_stream, int related_stream,

AVCodec **decoder_ret, int flags);

参数说明:

- `ic`:指向已打开媒体文件的 `AVFormatContext` 结构体的指

针。

- `type`:要查找的流类型,可以是 `AVMEDIA_TYPE_VIDEO`、

`AVMEDIA_TYPE_AUDIO` 等。

- `wanted_stream`:期望的流索引,如果为负值,则表示没有特

定的偏好。

- `related_stream`:相关流索引,用于查找与之相关的最佳流。

- `decoder_ret`:用于返回找到的解码器。

- `flags`:附加标志,可以用来指定额外的查找选项。

4、查找解码器

使用 avcodec_find_decoder() 查找符合指定解码器名称的解码

器。

函数原型如下:

AVCodec *avcodec_find_decoder(enum AVCodecID id);

参数说明:

- `id`:要查找的解码器的 ID。

5、初始化解码上下文

调用  avcodec_alloc_context3()  函数会为特定的编解码器分配一

个  AVCodecContext  结构体,并对其进行初始化。

AVCodecContext  结构体包含了编解码器的相关参数和状态信

息,比如编解码器类型、解码参数、帧率等。

函数原型如下:

AVCodecContext *avcodec_alloc_context3(const AVCodec

*codec);

参数说明:

- `codec`:指定要使用的编解码器,可以通过

`avcodec_find_decoder()` 或其他方式获取。

6、获取解码参数

调用 `avcodec_parameters_to_context()` 函数可以方便地将

`AVCodecParameters` 结构体中的参数(如编解码器类型、帧

率、分辨率等)复制到 `AVCodecContext` 结构体中,从而准备

进行编解码操作。

函数原型如下:

int avcodec_parameters_to_context(AVCodecContext *codec,

const AVCodecParameters *par);

参数说明:

- `codec`:要填充参数的 `AVCodecContext` 结构体指针。

- `par`:包含编解码器参数的 `AVCodecParameters` 结构体指

针。

7、打开解码器

调用 `avcodec_open2()` 函数可以打开并初始化指定的编解码器

上下文,使其准备好进行编解码操作。

函数原型如下:

int avcodec_open2(AVCodecContext *avctx, const AVCodec

*codec, AVDictionary **options);

参数说明:

- `avctx`:要打开和初始化的编解码器上下文。

- `codec`:要使用的编解码器,可以通过

`avcodec_find_decoder()` 或其他方式获取。

- `options`:可选的字典参数,用于设置编解码器的选项。

8、获取图像转换上下文

通过调用`sws_getContext`函数获取一个用于执行图像转换的上

下文对象,然后可以使用该上下文对象来进行图像转换操作。

函数原型如下:

struct SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat,
                                  int dstW, int dstH, enum AVPixelFormat dstFormat,
                                  int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param);

参数说明:

- `srcW`: 源图像的宽度

- `srcH`: 源图像的高度

- `srcFormat`: 源图像的像素格式

- `dstW`: 目标图像的宽度

- `dstH`: 目标图像的高度

- `dstFormat`: 目标图像的像素格式

- `flags`: 可以指定一些转换的选项

- `srcFilter`: 源图像滤镜

- `dstFilter`: 目标图像滤镜

- `param`: 一组额外的参数

9、读取视频源文件

调用 `av_read_frame()` 函数可以从输入文件或流中读取一帧音视

频数据,并将其存储在 AVPacket 结构体中。

函数原型如下:

int av_read_frame(AVFormatContext *s, AVPacket *pkt);

参数说明:

- `s`:输入文件或流的 AVFormatContext 上下文。

- `pkt`:存储读取到的音视频帧数据的 AVPacket 结构体。

12、发送音频数据到解码器

调用 `avcodec_send_packet()` 函数可以将 AVPacket 数据包发送

给解码器进行解码。在发送完所有数据包后,需要调用

`avcodec_send_packet()` 传递一个空的 AVPacket 指针,以便告

知解码器已经发送完所有数据。

函数原型如下:
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt);
参数说明:
- `avctx`:指向 AVCodecContext 结构体的指针,表示解码器上下文。
- `avpkt`:指向要发送给解码器的 AVPacket 数据包的指针。

13、从解码器接收解码后的视频数据

调用 `avcodec_receive_frame()` 函数可以从解码器中接收解码后

的音视频帧数据,并将其存储在 AVFrame 结构体中。


函数原型如下:

int avcodec_receive_frame(AVCodecContext *avctx, AVFrame

*frame);

参数说明:

- `avctx`:指向 AVCodecContext 结构体的指针,表示解码器上

下文。

- `frame`:用于存储接收到的解码后的 AVFrame 帧数据的结构体。

14、分配图像数据缓冲区

通过调用`av_image_alloc`函数为图像数据分配内存,并

将分配的内存绑定到指定的指针数组和行大小数组中,以便后续

在这些内存区域中存储图像数据。
 

函数原型如下所示:
int av_image_alloc(uint8_t *pointers[4], int linesizes[4], int w, int h, enum AVPixelFormat pix_fmt, int align);

参数解释:
- `pointers`: 用于存储图像数据的指针数组
- `linesizes`: 每个图像数据平面的行大小
- `w`: 图像宽度
- `h`: 图像高度
- `pix_fmt`: 像素格式
- `align`: 内存对齐参数


15、执行图像转换和缩放操作

通过调用`sws_scale`函数,可以使用提供的SwcContext对象和输入图像数据,对图像进行转换和缩放操作,然后将结果存储到输出图像数据中。

函数原型如下所示:
int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[]);

参数解释:

- `c`: SwsContext对象,用于存储图像转换相关信息

- `srcSlice`: 指向输入图像数据的指针数组

- `srcStride`: 输入图像每个平面的跨度(stride)

- `srcSliceY`: 输入图像的起始行

- `srcSliceH`: 输入图像的高度

- `dst`: 指向输出图像数据的指针数组

- `dstStride`: 输出图像每个平面的跨度(stride)

16、显示图像

直接显示执行 sws_scale 后的图像便可。

二、代码例程

音頻播放:点击跳转

視頻播放:点击跳转


觉得有帮助的话,打赏一下呗。。

           

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

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

相关文章

ideaSSM 工程车辆人员管理系统bootstrap开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 idea 开发 SSM 工程车辆人员管理系统是一套完善的信息管理系统,结合SSM框架和bootstrap完成本系统,对理解JSP java编程开发语言有帮助系统采用SSM框架(MVC模式开发),系统具 有完整的源代码和数据库&…

[AIGC] 在Spring Boot中指定请求体格式

在使用Spring Boot开发Web应用的时候,我们经常会遇到需要接收并处理HTTP请求的情况。一个HTTP请求通常包括一个请求行、若干请求头和一个请求体。请求体在POST和PUT请求中特别重要,因为它通常用于向服务器传递数据。 文章目录 创建并使用一个Java Bean指…

计算机二级Python基础操作题

题目来源:计算机二级Python半个月抱佛脚大法(内呈上真题版) - 知乎 第4,5,6,7,9,10,11套 1. 基础题1 sinput() print("{:\"^30x}".format(eval(s))) b …

【S5PV210】 | GPIO编程

【S5PV210】 | GPIO编程 时间:2024年3月17日22:02:32 目录 文章目录 【`S5PV210`】 | `GPIO`编程目录1.参考2.`DataSheet`2.1.概述2.1.1.特色2.1.2 输入/输出配置2.1.3 `S5PV210` 输入/输出类型2.1.4 IO驱动强度**2.1.4.1 类型A IO驱动强度****2.1.4.2 类型A IO驱动强度****2…

Selenium不同版本配置自动下载驱动及打包细节

Selenium配置浏览器驱动 自动下载浏览器驱动的方法 selenium4.7.0自动下载浏览器驱动的方法 selenium4.11.0 或4.11.1手动设置浏览器驱动路径的方法pyinstaller打包程序时同时打包ChromeDriverchromedriver路径需要sys._MEIPASS的路径进行引用方法一:通过–add-data…

LiveGBS流媒体平台GB/T28181功能-HTTPS 服务支持配置开启什么时候需要开启HTTPS测试SSL证书配置HTTPS测试证书

LiveGBS功能支持HTTPS 服务支持配置开启什么时候需要开启HTTPS测试SSL证书配置HTTPS测试证书 1、配置开启HTTPS1.1、准备https证书1.1.1、选择Nginx类型证书下载 1.2、配置 LiveCMS 开启 HTTPS1.2.1 web页面配置1.2.2 配置文件配置 2、HTTPS测试证书3、验证HTTPS服务4、为什么要…

安防监控视频汇聚平台EasyCVR接入海康Ehome设备,设备在线但视频无法播放是什么原因?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

python5:基于多进程的并发编程、基于协程的并发编程的学习笔记

进程 为什么要使用多进程?——GIL的存在,多线程实际不是并发执行 将任务分为两类:IO密集型(多线程)CPU密集型(多进程) 多进程的基本用法 concurrent.futures.process.ProcessPoolExecutor#进…

Airgorah:一款功能强大的WiFi安全审计工具

关于Airgorah Airgorah是一款功能强大的WiFi安全审计工具,该工具可以轻松发现和识别连接到无线接入点的客户端,并对特定的客户端执行身份验证攻击测试,捕捉WPA握手包,并尝试破解接入点的密码。在该工具的帮助下,广大研…

C语言联合体和枚举

前言 这篇博客就把剩下的两个自定义类型联合体和枚举好好总结一下,让我们好好看看联合体和枚举到底是什么 个人主页:小张同学zkf 若有问题 评论区见 感兴趣就关注一下吧 目录 1. 联合体 1.1 联合体类型的声明 1.2 联合体的特点 1.3 相同成员的结构体和联…

分类预测 | Matlab实现PSO-KELM粒子群优化算法优化核极限学习机分类预测

分类预测 | Matlab实现PSO-KELM粒子群优化算法优化核极限学习机分类预测 目录 分类预测 | Matlab实现PSO-KELM粒子群优化算法优化核极限学习机分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.MATLAB实现PSO-KELM粒子群优化算法优化核极限学习机分类预测(完整源…

ideaSSM 高校公寓交流员管理系统bootstrap开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 idea 开发 SSM 高校公寓交流管理系统是一套完善的信息管理系统,结合SSM框架和bootstrap完成本系统,对理解JSP java编程开发语言有帮助系统采用SSM框架(MVC模式开发),系统具有完整的源代码和数据库&…

C语言:自定义类型(结构体)

目录 一、结构的特殊声明二、结构的自引用三、结构体内存对齐1.对齐规则2.为什么存在内存对齐(1)平台原因 (移植原因):(2)性能原因: 3.修改默认对齐数 四、结构体传参五、结构体实现位段1.什么是位段2.位段的内存分配3.位段的跨平台问题4.位段使用的注意…

硬件工程师入门基础知识(四)多层陶瓷电容应用(三)

多层陶瓷电容应用(三) 1.开关电源输出滤波电容器如何选择和计算?2.线性电源和开关电源对于滤波电容的选择有何区别?3.哪些电路适合三端多层陶瓷电容?4.哪些电路适合金属支架多层陶瓷电容?1.开关电源输出滤波电容器如何选择和计算? 无论任何开关电源拓扑,其输出滤波的目…

乐得瑞科技PD协议芯片:OTG与充电并行,引领数据交互

在科技日新月异的今天,数据交互的方式对于我们的日常生活和工作都起到了至关重要的作用。但在OTG技术诞生之前,这一过程却显得相当繁琐和耗时。想象一下,你需要将数码相机的照片导入到笔记本电脑中,却不得不频繁地拔出内存卡&…

YOLOv5目标检测学习(6):源码解析之:训练部分train.py

文章目录 前言一、导入相关包与配置二、主函数main2.1 checks:检查rank值来判断是否打印参数、检查git仓库、检查包的安装2.2 判断是否恢复上一次模型训练提问:opt.data, opt.cfg, opt.hyp, opt.weights, opt.project各是什么? 2.3 DDP mode&…

基于JavaWeb+BS架构+SpringBoot+Vue+O2O生鲜食品订购小程序系统的设计和实现

基于JavaWebBS架构SpringBootVueO2O生鲜食品订购小程序系统的设计和实现 文末获取源码Lun文目录前言主要技术系统设计功能截图 文末获取源码 Lun文目录 目 录 摘 要 I Abstract II 1 绪 论 1 1.1课题研究背景及意义 1 1.2研究现状 1 1.3本论文的主要论文结构 3 2系统相关技术…

Qt实现TFTP Server和 TFTP Client(一)

1 概述 TFTP协议是基于UDP的简单文件传输协议,协议双方为Client和Server.Client和Server之间通过5种消息来传输文件,消息前两个字节Code是消息类型,消息内容随消息类型不同而不同。传输模式有三种:octet,netascii和mail,octet为二…

微服务cloud--抱团取暖吗 netflix很多停更了

抱团只会卷,卷卷也挺好的 DDD 高内聚 低耦合 服务间不要有业务交叉 通过接口调用 分解技术实现的复杂性,围绕业务概念构建领域模型;边界划分 业务中台: 数据中台: 技术中台: 核心组件 eureka&#x…

C/C++代码性能优化——编程实践

1. 编程实践 在一些关键的地方,相应的编程技巧能够给性能带来重大提升。 1.1. 参数传递 传递非基本类型时,使用引用或指针,这样可以避免传递过程中发生拷贝。参数根据是否需要返回,相应加上const修饰,代码更安全&am…