蓟县集团网站建设,资阳seo,用手机做网站的app,网络推广公司怎么运作目录
#x1f308;前言#x1f308;
#x1f4c1; 整体架构 详细流程
#x1f4c1; 数据流向
#x1f4c1; 队列设计编辑
#x1f4c1; 线程设计 #x1f4c1; 音视频同步
#x1f4c1; 音频输出设计
#x1f4c1; 视频输出设计
#x1f4c1; 总结 …目录
前言 整体架构 详细流程 数据流向 队列设计编辑 线程设计 音视频同步 音频输出设计 视频输出设计 总结 前言 这篇文章是我在学习FFmpeg时看到一位UP主的开源项目。我认为还是比较好认通过和这个项目可以快速入门FFmpeg 7。 因为种种原因目前网上关于FFmpeg 7.x 版本相关介绍太少并且相较于之前版本接口有很大变化学习途中可能有很大困恼。因此我希望通过这个项目和我的理解带大家快速入门FFmpeg以及7版本以上的接口使用流程。 这篇文章的图片和源码均来自B站UP主程序员老廖音视频入门必备项目-最新FFmpeg7.1播放器开发_哔哩哔哩_bilibili。 我也将该项目做了一遍并且将源码上传至Gitee大家可以直接进行下载。
AVPlayer: 本地音乐播放器FFmpeg SDL 整体架构 详细流程 1. 初始化创建并初始化必要的队列、线程和组件。
2. 媒体处理 i. 解复用线程从文件读取数据包。 ii. 解码线程将数据包解码为帧。 iii. 音视频输出模块将帧渲染输出。
3. 用户交互: 处理用户事件如暂停、退出等。
4. 资源释放: 程序结束时按照正确的顺序释放资源避免内存泄露。 数据流向
1. 解复用阶段 DemuxThread读取媒体文件 分离音视频数据包 将音视频包放入对应的AVPacketQueue 2. 解码阶段 DecodeThread从AVPacketQueue获取数据包 使用FFmpeg解码器解码数据包 生成音视频帧并放入AVFrameQueue 3. 渲染阶段 AudioOutput/VideoOutput从AVFrameQueue获取帧 处理帧数据(重采样、格式转换等) 通过SDL渲染到输出设备 队列设计
1. 模板设计使用C模板实现通用队列结构提高代码复用率
2. 线程安全使用互斥锁和条件变量保证多线程环境下的数据一致性
3. 特化实现为AVPacket和AVFrame提供特化队列处理FFmpeg资源的引用计数
4. 终止机制通过abort标志控制队列终止实现优雅退出
5. 资源管理 AVPacketQueue负责管理AVPacket资源使用av_packet_free释放 AVFrameQueue负责管理AVFrame资源使用av_frame_free释放 在Queue中加锁解锁的操作会用到两个管理类 (当然可以都使用第二个)
std::lock_guard (简单锁): 1. 轻量级, 性能更高, 无额外开销 2. 严格作用域锁: 不能手动控制 3. 不可转移所有权 4. 不支持条件变量
std::unique_lock (灵活锁): 1. 功能更强大, 有额外的状态存储 2. 支持手动的加锁解锁 3. 支持所有权转移 4. 支持条件变量 线程设计 1. 基类封装Thread基类封装线程创建启动和停止的通用逻辑
2. 虚函数机制通过纯虚函数Run要求派生类实现具体的业务逻辑
3. 状态控制使用abort控制线程循环状态实现退出
4. 资源管理: DemuxThread管理文件读取和格式解析资源(AVFormatContext) DecodeThread管理解码器资源(AVCodecContext)
5. 线程协作 通过队列实现线程间数据传递解耦生产者和消费者。 音视频同步 1. 主时钟选择 i. 使用音频PTS作为主时钟基准 ii. 音频在回调函数中更新时钟值 2. 视频同步策略 i. 计算视频帧PTS与当前音频时钟的差值 ii. 差值为正(视频超前)延迟显示 iii. 差值为负(视频滞后)立即显示 iiii. 差值过大考虑跳帧或重复帧 3. 时钟管理 i. AVSync类提供时钟读写接口 ii. 音频线程设置时钟 iii. 视频线程读取时钟 AVSync中记录一个动态变差值可以简单理解为记录音频的pts。 为什么不能直接保存音频的pts呢 pts只在音频回调时更新而视频可能在任意时刻查询 GetClock()。 如果音频回调间隔是 10ms而视频在两次回调之间查询 GetClock()它拿到的 pts是 过时的没有考虑这期间的时间流逝。 结果视频计算的时间偏差不准确导致音画不同步。 无法处理音频播放速度变化如加速、卡顿。 如果音频因缓冲不足而卡顿pts更新变慢但系统时间仍在流逝。 直接返回 _current_audio_pts无法反映这种延迟。 音频输出设计 声音输出模块负责从帧队列取出音频帧进行必要的重采样并通过SDL输出音频。 1. 初始化流程 i. 初始化SDL音频播放子系统 ii. 设置音频参数 iii. 设置音频回调函数 iiii. 创建重采样上下文如果需要
2. 回调机制 i. SDL音频系统在需要数据时调用设置的回调函数 ii. 回调函数从帧队列获取音频帧 iii. 根据需要进行重采样 使用SwrContext iiii. 将处理后的音频数据填充到SDL提供的缓冲区
3. 音频时钟 i. 以音频PTS为主时钟 ii. 在每次回调中更新音频时钟 iii. 作为视频同步的基准
4. 资源管理 i. 管理重采样上下文SwrContext ii. 管理音频缓冲区 iii. 在Delnit和析构函数中释放资源 AVRational 是 FFmpeg 中用于表示 分数有理数 的结构体主要用于时间基time base、帧率frame rate、采样率sample rate等场景 视频输出设计 画面输出模块负责从帧队列获取视频帧与音频同步并通过SDL渲染到屏幕 1. 初始化流程 初始化SDL视频子系统 创建窗口和渲染器 创建纹理用于视频渲染 2. 主循环机制 处理SDL事件(如退出、按键等) 刷新视频帧 控制帧率以实现音视频同步 3. 同步策略 比较视频帧PTS与音频时钟 如果视频超前等待适当时间再显示 如果视频滞后立即显示并可能丢帧 4. 渲染过程 将YUV数据更新到SDL纹理 将纹理渲染到窗口 释放已显示的帧
5. 资源管理 管理SDL资源(窗口、渲染器、纹理) 在DeInit和析构函数中释放资源 总结 以上就是该项目的整体流程相对来说还是比较简单的。我认为将这个项目跑一边对于重点代码写一遍那么对FFmpeg 7版本的接口就会有比较深刻的印象了例如解封装解码转码等内容。