ffplay分析 (视频从Frame(解码后)队列取数据到SDL输出)

《ffplay的数据结构分析》
《ffplay分析(从启动到读取线程的操作)》
《ffplay分析(视频解码线程的操作)》
《ffplay分析(音频解码线程的操作)》
《ffplay 分析(音频从Frame(解码后)队列取数据到SDL输出)》
《ffplay分析 (音视频同步:主时钟为音频)》
《ffplay分析 (暂停 / 播放处理)》
《ffplay分析 (seek操作处理)》
《ffplay源码(版本:ffmpeg-4.2.1)》

ffplay分析 (视频从解码后队列取数据到SDL输出)

  • 一、分析:
    • 1、main():在main()函数开始时有创建SDL窗口的处理
    • 2、read_thread():开启读取线程后,在read_thread()读取数据线程中设置视频流时调用set_default_window_size()设置显示窗口的默认大小和渲染区域大小
    • 3、set_default_window_size():判断命令行是否有指定宽高没有就使用帧宽高,作为窗口宽高调用calculate_display_rect()计算渲染区域
    • 4、calculate_display_rect():使用像素比例计算实际宽高比
    • 5、calculate_display_rect():首先使用高度为基准计算渲染区域,如果宽度大于实际窗口再以宽度为基准重新计算
    • 6、calculate_display_rect():计算保存返回上层的渲染区域参数
    • 7、event_loop():SDL的事件循环调用了refresh_loop_wait_event()进行更新显示和获取SDL事件(在主线程更新,event_loop()在主线程调用)
    • 8、refresh_loop_wait_event():调用SDL_PumpEvents()、SDL_PeepEvents()、获取SDL事件。如果没有事件才进入while更新画面,否则返回上一层处理相应事件。
    • 9、refresh_loop_wait_event():调用usleep()等待同步和设置remaining_time默认等待时间
    • 10、refresh_loop_wait_event():调用video_refresh()进行视频更新
    • 11、video_refresh():判断是否是实时流操作
    • 12、video_refresh():判断是否是音频流显示操作
    • 13、video_refresh():视频流显示操作,如果没有数据就什么不做
    • 14、video_refresh():获取上一帧显示的帧和将要显示的一帧,用来计算同步时间操作
    • 15、video_refresh():判断将要显示的一帧的序列与现在解码的不同就直接抛弃,重新获取
    • 16、video_refresh():判断是否是新的播放序列,重置is->frame_timer
    • 17、video_refresh():判断是否暂停,直接保持显示
    • 18、video_refresh():计算上一帧持续显示的时长
    • 19、video_refresh():根据计算得到的delay判断是否继续显示上一帧还是往下走继续更新
    • 20、video_refresh():根据is->frame_timer用于下一轮的操作
    • 21、video_refresh():更新当前的视频时钟
    • 22、video_refresh():判断是否进行丢帧处理
    • 23、video_refresh():调用frame_queue_next()移动到下一帧
    • 24、video_refresh():调用video_display()真正开始渲染画面的操作
    • 25、video_display():判断是视频流调用video_image_display()显示
    • 26、video_image_display():获取将要显示的这一帧![在这里插入图片描述](https://img-blog.csdnimg.cn/20210128164947276.png)
    • 27、video_image_display():调用calculate_display_rect()根据窗口比例计算渲染区域(图像)的宽高,调用upload_texture()将frame的yuv更新到is->vid_texture(SDL_Texture)
    • 28、video_display():video_image_display()结束后,返回到video_display()最终调用SDL_RenderPresent()显示画面

一、分析:

1、main():在main()函数开始时有创建SDL窗口的处理

在这里插入图片描述

2、read_thread():开启读取线程后,在read_thread()读取数据线程中设置视频流时调用set_default_window_size()设置显示窗口的默认大小和渲染区域大小

在这里插入图片描述

3、set_default_window_size():判断命令行是否有指定宽高没有就使用帧宽高,作为窗口宽高调用calculate_display_rect()计算渲染区域

在这里插入图片描述

4、calculate_display_rect():使用像素比例计算实际宽高比

在这里插入图片描述

5、calculate_display_rect():首先使用高度为基准计算渲染区域,如果宽度大于实际窗口再以宽度为基准重新计算

在这里插入图片描述

6、calculate_display_rect():计算保存返回上层的渲染区域参数

在这里插入图片描述

7、event_loop():SDL的事件循环调用了refresh_loop_wait_event()进行更新显示和获取SDL事件(在主线程更新,event_loop()在主线程调用)

在这里插入图片描述

8、refresh_loop_wait_event():调用SDL_PumpEvents()、SDL_PeepEvents()、获取SDL事件。如果没有事件才进入while更新画面,否则返回上一层处理相应事件。

在这里插入图片描述

9、refresh_loop_wait_event():调用usleep()等待同步和设置remaining_time默认等待时间

在这里插入图片描述

10、refresh_loop_wait_event():调用video_refresh()进行视频更新

在这里插入图片描述

11、video_refresh():判断是否是实时流操作

在这里插入图片描述

12、video_refresh():判断是否是音频流显示操作

在这里插入图片描述

13、video_refresh():视频流显示操作,如果没有数据就什么不做

在这里插入图片描述

14、video_refresh():获取上一帧显示的帧和将要显示的一帧,用来计算同步时间操作

在这里插入图片描述

15、video_refresh():判断将要显示的一帧的序列与现在解码的不同就直接抛弃,重新获取

在这里插入图片描述

16、video_refresh():判断是否是新的播放序列,重置is->frame_timer

在这里插入图片描述

17、video_refresh():判断是否暂停,直接保持显示

在这里插入图片描述

18、video_refresh():计算上一帧持续显示的时长

在这里插入图片描述

19、video_refresh():根据计算得到的delay判断是否继续显示上一帧还是往下走继续更新

在这里插入图片描述

20、video_refresh():根据is->frame_timer用于下一轮的操作

在这里插入图片描述

21、video_refresh():更新当前的视频时钟

在这里插入图片描述

22、video_refresh():判断是否进行丢帧处理

在这里插入图片描述

23、video_refresh():调用frame_queue_next()移动到下一帧

在这里插入图片描述

24、video_refresh():调用video_display()真正开始渲染画面的操作

在这里插入图片描述

25、video_display():判断是视频流调用video_image_display()显示

在这里插入图片描述

26、video_image_display():获取将要显示的这一帧在这里插入图片描述

27、video_image_display():调用calculate_display_rect()根据窗口比例计算渲染区域(图像)的宽高,调用upload_texture()将frame的yuv更新到is->vid_texture(SDL_Texture)

在这里插入图片描述

28、video_display():video_image_display()结束后,返回到video_display()最终调用SDL_RenderPresent()显示画面

在这里插入图片描述

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

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

相关文章

线性结构节点类型(三)

一、线性结构 特点 第一个数据元素没有前驱最后一个数据元素没有后继1:1逻辑上相邻、物理上也相邻 类型 线性表(就是一张二维表)(为主研究对象)栈队列 学习方法 画逻辑结构—>定义存储结构—>实现相应的操作 二、线性表 线性结构 逻辑上的1:1存储结构 顺序存储结…

PL/SQL详细介绍

PL/SQL笔记PL/SQL块中只能直接嵌入SELECT,DML(INSERT,UPDATE,DELETE)以及事务控制语句(COMMIT,ROLLBACK,SAVEPOINT),而不能直接嵌入DDL语句(CREATE,ALTER,DROP)和DCL语句(GRANT,REVOKE) 1.检索单行数据 1.1使用标量变量接受数据 v_ename emp.ename%type; v_sal emp.sal%…

redis 备份导出rdb_Redis数据迁移利器之redisshake

“当需要进行Redis实例或集群数据迁移时,我们可以采用导出/导入的方式进行数据迁移,但当需要做数据异地灾备或双活时,再使用传统的方式就不合适了,我们需要借助工具(如redis-port/redis-shake)来完成。”redis-shake介绍redis-sha…

从Live Space搬家到这里

听说Live Space很快要关闭了,所以从http://peking2toronto.spaces.live.com/搬家到这里。转载于:https://www.cnblogs.com/pentest/archive/2010/08/29/1811726.html

java 方法 示例_Java Collectionsfrequency()方法与示例

java 方法 示例集合类的frequency()方法 (Collections Class frequency() method) frequency() method is available in java.util package. frequency()方法在java.util包中可用。 frequency() method is used to return the frequency of the given Object (obj) to the give…

线性结构常规操作(四)

定义存储结构(以单向链表为主) 对于链表的定义,通过结构体进行定义,包括两部分,一是数据域,另一个就是指针,用于指向下一个节点。 1,创建链表 定义链表: struct nodesq{int data;//数据域&a…

ffplay分析 (暂停 / 播放处理)

《ffplay的数据结构分析》 《ffplay分析(从启动到读取线程的操作)》 《ffplay分析(视频解码线程的操作)》 《ffplay分析(音频解码线程的操作)》 《ffplay 分析(音频从Frame(解码后)队列取数据到…

源码 状态机_[源码阅读] 阿里SOFA服务注册中心MetaServer(1)

[源码阅读] 阿里SOFA服务注册中心MetaServer(1)0x00 摘要0x01 服务注册中心1.1 服务注册中心简介1.2 SOFARegistry 总体架构1.3 为什么要分层0x02 MetaServer2.1简介2.2 问题0x03 代码结构0x04 启动运行4.1 集成部署4.2 独立部署0x05 总体逻辑5.1 程序主体5.2 配置0x06 启动6.1…

HttpService远程校验

今天学了下HttpService,和大家分享一下。HttpService是用来读取远程数据的一个对象,数据格式为XML。 我做了一个登陆校验的功能,主要是通过HttpService将服务器端的用户数据得到,然后在客户端判断输入的用户名和密码是否存在。 主…

免费开源FTP Server软件FileZilla Server

很多朋友在实际应用中都可能需要用到FTP Server类的软件,这类软件有很多,比较知名的有Serv-U、G6等,这里向大家介绍一下FileZilla Server,Windows平台下一款不错的FTP Server软件,而且是免费的、开源的。 S…

Java BigDecimal floatValue()方法与示例

BigDecimal类floatValue()方法 (BigDecimal Class floatValue() method) floatValue() method is available in java.math package. floatValue()方法在java.math包中可用。 floatValue() method is used to convert a BigDecimal to a float value and when this BigDecimal m…

明明的随机数(快排)

明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数…

ffplay分析 (seek操作处理)

《ffplay的数据结构分析》 《ffplay分析(从启动到读取线程的操作)》 《ffplay分析(视频解码线程的操作)》 《ffplay分析(音频解码线程的操作)》 《ffplay 分析(音频从Frame(解码后)队列取数据到…

android 代码设置 键盘适应_硬核软件,能在电脑上控制iPhone和Android手机

在电脑上控制手机大概已经不是什么新鲜操作,小米、华为都为自家手机和电脑的联动推出了同屏操作之类的功能,此外也可以通过开源软件Scrcpy来在Windows或者macOS上实现对安卓手机的控制,这些基本都只针对安卓手机。近期,奇客君发现…

网址出现error.aspx?aspxerrorpath=404.htm?aspxerrorpath=的原因及解决办法转

网址出现aspxerrorpath的问题描述 1.网页打不开了,输入网址后就提示error.aspx?aspxerrorpath/about-us.html,到底是什么原因啊? 2.ASP网站自定义了404错误页,但访问不存在的网址时网址错误页后面总多出aspxerrorpath参数,怎么解…

ruby hash方法_Ruby中带有示例的Hash.default(key = nil)方法

ruby hash方法Hash.default(key nil)方法 (Hash.default(keynil) Method) In this article, we will study about Hash.default(keynil) Method. The working of this method can be predicted with the help of its name but it is not as simple as it seems. Well, we will…

回文数、括号匹配(栈操作)

回文数 “xyzyx”是一个回文字符串,所谓回文字符串就是指正读反读均相同的字符序列,如“席主席”、“记书记”、“aha”和“ahaha”均是回文,但“ahah”不是回文。输入一行字符(仅包含小写英文字母a~z)请判断这行字符…

ijkplayer 消息循环处理过程分析

ijkplayer 消息循环处理过程分析简介一、消息队列初始化1、 initWithContentURLString函数2、 ijkmp_ios_create函数3、 ijkmp_create函数二、消息队列的消息循环处理函数启动1、prepareToPlay函数2、ijkmp_prepare_async函数3、ijkmp_prepare_async_l函数4、ijkmp_msg_loop函数…

json解析对应的value为null_徒手撸一个JSON解析器

Java大联盟致力于最高效的Java学习关注作者 | 田小波cnblogs.com/nullllun/p/8358146.html1、背景JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。相对于另一种数据交换格式 XML,JSON 有着诸多优点。比如易读性更好,占用空间更少等。在 …

[一]设计模式初探

模式,顾名思义,就是做一种事情的方法归纳,就经验来说,做什么事情有个好的方法来应对都是可以事半功倍的,在软件开发中何谓好的模式? 我认为好的模式简单来说就是保证你应对需求变化的时候不用做更多的代码修改&#x…