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

news2024/9/29 23:38:24

一、视频播放流程

(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.coloradmin.cn/o/1537950.html

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

相关文章

Flask python 开发篇:链接mysql

一、历史回顾 根据上一篇:配置文件编写,已经把各种配置根据开发环境做了区分,再config.py中,我们可以分别处理测试、生产的相关配置,这节主要说一下数据库的链接和使用 二、配置数据库连接 Flask定义和链接数据库文…

手机可以格式化存储卡吗?格式化以后出现什么情况

随着智能手机的普及,存储卡(如SD卡、MicroSD卡等)已成为手机存储扩展的重要工具。然而,在使用过程中,我们有时可能会遇到需要格式化存储卡的情况。那么,手机能否直接格式化存储卡呢?格式化后存储…

【Flutter学习笔记】10.3 组合实例:TurnBox

参考资料:《Flutter实战第二版》 10.3 组合实例:TurnBox 这里尝试实现一个更为复杂的例子,其能够旋转子组件。Flutter中的RotatedBox可以旋转子组件,但是它有两个缺点: 一是只能将其子节点以90度的倍数旋转二是当旋转…

在服务器(Ubuntu20.04)安装用户级别的cuda11.8(以及仿照前面教程安装cuda11.3后安装cudnn和pytorch1.9.0)

1、cuda11.8的下载 首先在cuda官网下载我们需要的cuda版本,这里我下载的是cuda11.8(我的最高支持cuda12.0) 这里我直接使用wget命令下载不了,于是我直接在浏览器输入后面的链接下载到本地,之后再上传至服务器的&am…

数据分析概述、Conda环境搭建及JupyterLab的搭建

1. 数据分析职责概述 当今世界对信息技术的依赖程度在不断加深,每天都会有大量的数据产生,我们经常会感到数据越来越多,但是要从中发现有价值的信息却越来越难。这里所说的信息,可以理解为对数据集处理之后的结果,是从…

SQLiteC/C++接口详细介绍sqlite3_stmt类(十)

返回:SQLite—系列文章目录 上一篇:SQLiteC/C接口详细介绍sqlite3_stmt类(九) 下一篇: SQLiteC/C接口详细介绍sqlite3_stmt类(十一) 38、sqlite3_column_value sqlite3_column_valu…

Python:熟悉简单的skfuzzy构建接近生活事件的模糊控制器”(附带详细注释说明)+ 测试结果

参考资料:https: // blog.csdn.net / shelgi / article / details / 126908418 ————通过下面这个例子,终于能理解一点模糊理论的应用了,感谢原作。 熟悉简单的skfuzzy构建接近生活事件的模糊控制器 假设下面这样的场景, 我们希望构建一套…

linux系统------------MySQL 存储引擎

目录 一、存储引擎概念介绍 二、常用的存储引擎 2.1MyISAM 2.1.1MYlSAM的特点 2.1.2MyISAM 表支持 3 种不同的存储格式⭐: (1)静态(固定长度)表 (2)动态表 (3)压缩表 2.1.3MyISAM适…

基于python+vue食品安全信息管理系统flask-django-nodejs-php

食品安全信息管理系统设计的目的是为用户提供食品信息、科普专栏、食品检测、检测结果、交流论坛等方面的平台。 与PC端应用程序相比,食品安全信息管理系统的设计主要面向于用户,旨在为管理员和用户提供一个食品安全信息管理系统。用户可以通过APP及时查…

Gitlab介绍

1.什么是Gitlab GitLab是一个流行的版本控制系统平台,主要用于代码托管、测试和部署。 GitLab是基于Git的一个开源项目,它提供了一个用于仓库管理的Web服务。GitLab使用Ruby on Rails构建,并提供了诸如wiki和issue跟踪等功能。它允许用户通…

欧科云链:2024将聚焦发展与安全,用技术助力链上数据安全和合规

近期,OpenAI和Web3.0两大新技术发展势头迅猛。OpenAI 再次引领AI领域的新浪潮,推出了创新的文本转视频模型——Sora,Sora 可以创建长达60 秒的视频,包含高度详细的场景、複杂的摄像机运动以及情感丰富角色,再次将AI 的…

Django在日志中使用AdminEmailHandler发送邮件(同步),及celery异步发送日志邮件的实现

目录 一、使用AdminEmailHandler实现发送日志通知邮件 1,配置日志项 2,配置邮件项 3,在视图里使用日志 二、继承AdminEmailHandler使用celery实现异步发送邮件 1,安装配置celery 2,继承AdminEmailHandler类&…

python食品安全信息管理系统flask-django-nodejs-php

。 食品安全信息管理系统是在安卓操作系统下的应用平台。为防止出现兼容性及稳定性问题,编辑器选择的是Hbuildex,安卓APP与后台服务端之间的数据存储主要通过MySQL。用户在使用应用时产生的数据通过 python等语言传递给数据库。通过此方式促进食品安全信…

VMware 15 中 Ubuntu与windows 10共享文件夹设置

wmware 15.5.7中安装ubuntu 22.04 物理机为windows 10 1.选中ubuntu中想要共享的文件夹右击,点属性 2.在Local network share中勾选share this folder,第一次会提示你安装samba,安装即可 3.window10的资源管理器中使用 虚拟机计算机名即可…

无人机采集图像的相关知识

1.飞行任务规划 一般使用飞行任务规划软件进行飞行任务的设计,软件可以自动计算相机覆盖和图像重叠情况。比如ArduPilot (ArduPilot - Versatile, Trusted, Open) 和UgCS (http://www.ugcs.com)是两个飞行任务规划软件,可以适用大多数无人机系统。 2.图…

如何减少pdf的文件大小?pdf压缩工具介绍

文件发不出去,有时就会耽误工作进度,文件太大无法发送,这应该是大家在发送PDF时,常常会碰到的问题吧,那么PDF文档压缩大小怎么做呢?因此我们需要对pdf压缩后再发送,那么有没有好用的pdf压缩工具…

解决IE11报错:CSS 因 Mime 类型不匹配而被忽略

简要概述: 本人用springboot开发网站,手动处理js和css文件请求,报错:CSS 因 Mime 类型不匹配而被忽略 后台代码: 如下三个代码块 GetMapping("/Guest/ASN1/{FileName}")public void GetFiles(PathVariab…

阿里云 EMR Serverless Spark 版免费邀测中

随着大数据应用的广泛推广,企业对于数据处理的需求日益增长。为了进一步优化大数据开发流程,减少企业的运维成本,并提升数据处理的灵活性和效率,阿里云开源大数据平台 E-MapReduce (简称“EMR”)正式推出 E…

SQL中条件放在on后与where后的区别

数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。 在使用left jion时,on和where条件的区别如下: on条件是在生成临时表时使用的条件,不管on中的条件是否为真&…

深度学习Top10算法之深度神经网络DNN

深度神经网络(Deep Neural Networks,DNN)是人工神经网络(Artificial Neural Networks,ANN)的一种扩展。它们通过模仿人脑的工作原理来处理数据和创建模式,广泛应用于图像识别、语音识别、自然语…