已解决
【音视频】ffplay源码解析-FrameQueue队列
来自网友在路上 159859提问 提问时间:2023-09-22 12:54:48阅读次数: 59
最佳答案 问答题库598位专家为你答疑解惑
帧队列架构位置
结构体源码
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/1int uploaded; // 用来记录该帧是否已经显示过?int flip_v; // =1则旋转180, = 0则正常播放
} Frame;
内存管理
- 一个环形循环数组队列
- 数组队列适合于事先明确了缓冲区的最⼤容量的情形
- 避免假队空----定义一个size
- 写端位于解码线程,读端位于播放线程
- 锁机制—线程安全
引申知识点—队列假队空
概念
如果只用一个连续数组表示一个队列,没有其他标志位
则
- 队空:头指针==尾指针
- 队满:头指针==尾指针
则无法判断队列状态是队满还是队空
解决办法
一共有三种解决办法
- 方法1:数组最后一个空间不存放元素
- 方法2:加一个当前元素数量size
- 方法3:加一个队满标志位flag
队列大小设置
因为这⾥存储的是解码后的数据,队列缓存不宜设置过⼤
一般为限制缓存
视频帧队列<=3
音频帧队列<=9
字幕帧队列<=16
查看全文
99%的人还看了
相似问题
猜你感兴趣
版权申明
本文"【音视频】ffplay源码解析-FrameQueue队列":http://eshow365.cn/6-11426-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!
- 上一篇: 【计算机网络】传输层协议——TCP(中)
- 下一篇: 专题9 导数的几何意义、相关变化率