【音视频】ffplay源码解析-FrameQueue队列

2023-09-17 15:47:47

帧队列架构位置

在这里插入图片描述


结构体源码

FrameQueue结构体

/* 这是一个循环队列,windex是指其中的首元素,rindex是指其中的尾部元素. */
typedef struct FrameQueue {
    Frame	queue[FRAME_QUEUE_SIZE];        // FRAME_QUEUE_SIZE  最大size, 数字太大时会占用大量的内存,需要注意该值的设置
    int		rindex;                         // 读索引。待播放时读取此帧进行播放,播放后此帧成为上一帧
    int		windex;                         // 写索引
    int		size;                           // 当前总帧数
    int		max_size;                       // 可存储最大帧数
    int		keep_last;                      // = 1说明要在队列里面保持最后一帧的数据不释放,只在销毁队列的时候才将其真正释放
    int		rindex_shown;                   // 初始化为0,配合keep_last=1使用
    SDL_mutex	*mutex;                     // 互斥量
    SDL_cond	*cond;                      // 条件变量
    PacketQueue	*pktq;                      // 数据包缓冲队列
} FrameQueue;

Frame结构体

// 用于缓存解码后的数据
typedef struct Frame {
    AVFrame		*frame;         // 指向数据帧
    AVSubtitle	sub;            // 用于字幕
    int		serial;             // 帧序列,在seek的操作时serial会变化
    double		pts;            // 时间戳,单位为秒
    double		duration;       // 该帧持续时间,单位为秒
    int64_t		pos;            // 该帧在输入文件中的字节位置
    int		width;              // 图像宽度
    int		height;             // 图像高读
    int		format;             // 对于图像为(enum AVPixelFormat),
                                // 对于声音则为(enum AVSampleFormat)
    AVRational	sar;            // 图像的宽高比(16:9,4:3...),如果未知或未指定则为0/1
    int		uploaded;           // 用来记录该帧是否已经显示过?
    int		flip_v;             // =1则旋转180, = 0则正常播放
} Frame;

内存管理

  • 一个环形循环数组队列
    • 数组队列适合于事先明确了缓冲区的最⼤容量的情形
    • 避免假队空----定义一个size
  • 写端位于解码线程,读端位于播放线程
  • 锁机制—线程安全

引申知识点—队列假队空

概念

如果只用一个连续数组表示一个队列,没有其他标志位

  • 队空:头指针==尾指针
  • 队满:头指针==尾指针

则无法判断队列状态是队满还是队空

解决办法

一共有三种解决办法

  • 方法1:数组最后一个空间不存放元素
  • 方法2:加一个当前元素数量size
  • 方法3:加一个队满标志位flag

队列大小设置

因为这⾥存储的是解码后的数据,队列缓存不宜设置过⼤

一般为限制缓存

视频帧队列<=3

音频帧队列<=9

字幕帧队列<=16

在这里插入图片描述

更多推荐

简单工厂模式 和 工厂方法 和 抽象工厂的区别

简单工厂模式、工厂方法模式和抽象工厂模式是三种不同的创建型设计模式,它们在对象的创建和封装方面有不同的用途和实现方式。以下是它们之间的主要区别:1.**简单工厂模式(SimpleFactoryPattern)**:-**目的**:简单工厂模式的主要目的是封装对象的创建逻辑,以便客户端代码无需知道具体对象的创建细节。它将

展会预告 | 图扑邀您共聚 IOTE 国际物联网展·深圳站

参展时间:9月20日-22日图扑展位:9号馆9B35-1参展地址:深圳国际会展中心(宝安新馆)IOTE2023第二十届国际物联网展·深圳站,将于9月20日-22日在深圳国际会展中心(宝安)9、10、11号馆震撼来袭。本届展会以“IoT构建数字经济底座”为主题,将IoT技术引入实体经济领域,促进数字化转型和智能化升级,推

基于Java+SpringBoot+Vue前后端分离旅游网站设计和实现

博主介绍:✌全网粉丝30W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌🍅文末获取源码联系🍅👇🏻精彩专栏推荐订阅👇🏻不然下次找不到哟2022-2024年最全的计算机软件毕业设计选题

基于Java旅游管理系统设计实现(源码+lw+部署文档+讲解等)

博主介绍:✌全网粉丝30W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌🍅文末获取源码联系🍅👇🏻精彩专栏推荐订阅👇🏻不然下次找不到哟2022-2024年最全的计算机软件毕业设计选题

python经典百题之最大公约数与最小公倍数

题目:输入两个正整数m和n,求其最大公约数和最小公倍数。方法1:辗转相除法(欧几里德算法)求最大公约数defgcd_euclidean(m,n):whilen:m,n=n,m%nreturnmm=36n=48gcd_result=gcd_euclidean(m,n)print("GCD:",gcd_result)#计算

echarts-可视化地图防重叠文本框

我在第一篇可视化地图中,有一些基础介绍,本篇文章就是多展示一些效果,大家可以按需获取。先直接上效果图这里的配置项有用到1、通过geo展示多层地图,这样可以像上图所示,通过错位有了一些3D效果;2、北京的特殊图标展示通过scatter类型实现;3、区域散点图effectScatter类型;4、有方向流动的线,lines类

Vue2023 面试归纳及复习(2)

1vue3中的动态组件和KeepAlive组件动态组件component<component>动态组件是一种可以根据数据变化而动态加载不同组件的方式。使用动态组件可以有效地减少代码复杂度,提高组件的复用性和灵活性。动态组件通过一个特殊的属性is来实现动态加载,is的值可以是组件的名称或组件对象。KeepAliveKee

设计模式-责任链模式

“单一职责原则”要求一个类仅负责的一个不可分业务逻辑,但这并不意味着能够实现这部分业务逻辑的只能有一个类,业务逻辑可能是会因运行时数据而选择不同类。比如在日常工作中,请假审批可能受请假天数、请假类型等因素影响,而须由不同领导来负责审批。再比如在银行取钱时,取钱业务审批申请可能会受到你所取钱总数、存储类型等因素影响,而须

node 之 express 框架(初级)

一、express热更新1、安装扩展npminstallnode-dev-D2、在根目录下的package.json文件中进行配置3、之后的启动执行下面的命令即可npmrundev二、mvc中的模板引擎1、ejs模板引擎的安装npminstallejs-s2、在根目录下的app.js文件中配置app.set('view

【计算机毕业设计】基于SpringBoot+Vue网络云端日记本系统的设计与实现

博主主页:一季春秋博主简介:专注Java技术领域和毕业设计项目实战、Java、微信小程序、安卓等技术开发,远程调试部署、代码讲解、文档指导、ppt制作等技术指导。主要内容:毕业设计(Java项目、小程序等)、简历模板、学习资料、面试题库、技术咨询。🍅文末获取联系🍅精彩专栏推荐订阅👇🏻👇🏻不然下次找不到哟Sp

C#回调函数学习1

回调函数(CallbackFunction)是一种函数指针,它指向的是由用户自己定义的回调函数。我们将这个回调函数的指针作为参数传递给另外一个函数,在这个函数工作完成后,它将通过这个回调函数的指针来回调通知调用者处理结果。此定义来自网上;看一个例子;这是用委托实现的回调函数;usingSystem;usingSyste

热文推荐