音视频项目—基于FFmpeg和SDL的音视频播放器解析(九)

news/2025/3/31 13:40:50/

介绍

在本系列,我打算花大篇幅讲解我的 gitee 项目音视频播放器,在这个项目,您可以学到音视频解封装,解码,SDL渲染相关的知识。您对源代码感兴趣的话,请查看基于FFmpeg和SDL的音视频播放器

如果您不理解本文,可参考我的前一篇文章音视频项目—基于FFmpeg和SDL的音视频播放器解析(八)

解析

这篇文章我们会解析项目的父类 Queue,其子类 AVPacketQueue 和 AVFrameQueue 均需要继续其特性。

我们先大体看一下 Queue 的源码

#pragma once
#ifndef QUEUE_H_
#define QUEUE_H_
#include<mutex>
#include<condition_variable>
#include<queue>
using namespace std;template<typename T>
class Queue
{
public:Queue(){}~Queue(){}void Abort() {abort = 1;cond_t.notify_all();}int Push(T val) {lock_guard<mutex> lock(mutex_t);if (abort == 1) {return -1;}queue_t.push(val);cond_t.notify_one();return 0; }int Pop(T& val, int timeout = 0) {unique_lock<mutex> lock(mutex_t);if (queue_t.empty()) {cond_t.wait_for(lock, chrono::milliseconds(timeout), [this] {return !queue_t.empty() | abort;});}if (abort == 1) {return -1;}if (queue_t.empty()) {return -2;}val = queue_t.front();queue_t.pop();return 0;}int Front(T& val) {lock_guard<mutex> lock(mutex_t);if (abort == 1) {return -1;}if (queue_t.empty()) {return -2;}val = queue_t.front();return 0;}int Size() {lock_guard<mutex> lock(mutex_t);return queue_t.size(); }
private:int abort = 0;mutex mutex_t;condition_variable cond_t;queue<T> queue_t;
};#endif

Queue 将声明与实现写在一起了,所以看上去比较多,其实函数只有 Abort,Push,Pop,Front,Size 这五个。

我们先看看私有成员。

abort:标识位,判断能不能接收数据

mutex:互斥锁

condition_variable:条件变量

queue:队列

说明一下,在代码当中,我们为什么要使用互斥锁,由于我们采用多线程并发的机制,为实现线程安全,我们就采用互斥锁。而条件变量是和互斥锁一起使用的。想深入了解的朋友可看条件变量(condition_variable)

然后我们看一下公有成员函数

Abort:
void Abort() {abort = 1;cond_t.notify_all();
}

这个函数负责终止程序并通知所有线程。

Push:
int Push(T val) {lock_guard<mutex> lock(mutex_t);if (abort == 1) {return -1;}queue_t.push(val);cond_t.notify_one();return 0; 
}

这个函数负责队列增加数据,上锁,增加数据,通知线程。

Pop:
int Pop(T& val, int timeout = 0) {unique_lock<mutex> lock(mutex_t);if (queue_t.empty()) {cond_t.wait_for(lock, chrono::milliseconds(timeout), [this] {return !queue_t.empty() | abort;});}if (abort == 1) {return -1;}if (queue_t.empty()) {return -2;}val = queue_t.front();queue_t.pop();return 0;
}

这个函数负责队列弹出头部数据,上锁,如果队列为空,等待。当不为空时,赋值给参数并弹出数据。

Front:
int Front(T& val) {lock_guard<mutex> lock(mutex_t);if (abort == 1) {return -1;}if (queue_t.empty()) {return -2;}val = queue_t.front();return 0;
}

这个函数负责返回队列头部数据。上锁,判断是否为空,不为空则返回数据。

Size:
int Size() {lock_guard<mutex> lock(mutex_t);return queue_t.size(); 
}

这个函数负责返回队列的大小。上锁,返回队列大小。

好了,我们今天介绍了父类 Queue,大家感到困难的话,因为是由于互斥锁和条件变量的原因,如果采用单线程开发的话,就不用这么麻烦,但是为了提高性能,采用多线程,保证安全性,就要麻烦一点。

那么接下来我们就可以讲 Queue 的子类,avpacketqueue 和 avframequeue 了。

欲知后事如何,请听下回分解。


http://www.ppmy.cn/news/1227406.html

相关文章

ffmpeg知识点整理

使用FFmepg进行视频转码、视频格式转换、图片提取等&#xff01;_ffmepg -c:v-CSDN博客 中文文档&#xff1a; ffmpeg 中文手册 (beandrewang.github.io) 笔记&#xff1a; 通用规则是&#xff0c;所有选项作用于其后边的第一个文件。因此&#xff0c;顺序是非常重要的&…

AUTODL云服务器使用大致步骤(适合本人版)

(一)在官网上创建一个服务器 (二)远程连接指令&#xff1a; 改为&#xff1a; (三)连接后&#xff0c;可在中进行代码运行 输入一些指令 python ......

038、语义分割

之——介绍与数据集 杂谈 语义分割&#xff0c;语义分割(Semantic Segmentation)方法-CSDN博客&#xff1a; 语义分割是计算机视觉领域的一项重要任务&#xff0c;旨在将图像中的每个像素分配到其对应的语义类别中。与物体检测或图像分类不同&#xff0c;语义分割不仅要识别图像…

iOS_折叠展开 FoldTextView

1. 显示效果 Test1&#xff1a;直接使用&#xff1a; Test2&#xff1a;在 cell 里使用&#xff1a; 2. 使用 2.1 直接使用 // 1.1 init view private lazy var mooFoldTextView: MOOFoldTextView {let view MOOFoldTextView(frame: .zero)view.backgroundColor .cyanvie…

Nodejs中net模块多次Socket.setTimeout无法覆盖之前函数,导致叠加执行问题解决

Hi, I’m Shendi Nodejs中net模块多次Socket.setTimeout无法覆盖之前函数&#xff0c;导致叠加执行问题解决 问题描述 在 Nodejs 中&#xff0c;net 模块的 Socket 的 setTimeout 函数是设置超时时间&#xff0c;如果多次设置&#xff0c;超时时间会是最后一次的时间&#xff…

pm2在Windows环境中的使用

pm2 进程管理工具可以Windows操作系统上运行&#xff0c;当一台Windows电脑上需要运行多个进程时&#xff0c;或者运维时需要运行多个进程以提供服务时。可以使用pm2&#xff0c;而不再是使用脚本。 1. 使用PM2管理进程 1.1. 启动PM2项目 1.1.1. 直接启动项目 参数说明&…

使用Spring Boot结合JustAuth实现支付宝、微信、微博扫码登录功能

使用Spring Boot结合JustAuth实现支付宝、微信、微博扫码登录功能 在使用Spring Boot结合JustAuth实现支付宝、微信、微博扫码登录功能之前&#xff0c;需要先确保已经配置好Spring Boot项目&#xff0c;并且添加了JustAuth的依赖。你可以在项目的pom.xml文件中添加如下依赖&a…

【测开求职】面试题:HR面相关的开放性问题

每一面可能都会穿插一些岗位理解的问题,有一些问题是真的挺不好回答的,最好还是提前准备一下,本篇文章总结了在面测试开发岗位中遇到的一些开放性问题👉 目录 💗如何理解测试开发💗为什么选择测试💗如何学习测试开发近期的职业规划前面面试的总结说一下你的优缺点最…