自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(43)
  • 收藏
  • 关注

原创 [mpv架构] (6) mpv的退出机制 ——拆解 abort、优雅关闭与超时取消

按 `q`,mpv 立刻退出。可此时 demux 线程可能正卡在 `recv()` 里,curl 线程卡在 `mp_cond_wait` 里,解码线程在等新的 packet——它们没被 `kill`,也没读你的键盘。谁,在什么时刻,用什么方式通知它们的?

2026-11-09 23:27:54 230

原创 [mpv架构] (7) mpv的解码器,为什么要叠四层 filter?解码器的装配结构与策略选择

当你真去源码里找mpv的解码器,会直接迷失在复杂的结构里,decode_wrapper/decode/vd_lavc 都像是解码器, 那么数据到底是怎么从packet流向frame的?这篇文章就来拆开这个"解码器",看看它的**装配结构、策略选择**。

2026-09-15 09:01:58 325

原创 [mpv架构] (5) mpv播放器为什么能无延迟 seek 到指定位置?

一个看似平凡的问题:播放中拖进度条到 10 分钟后,播放器要做什么?

2026-09-05 14:55:26 351

原创 [mpv架构] (4) demux线程预读与水位控制

前文结束时,demux 线程已经启动、轨道已选好、decoder 已经就位——一切准备就绪。从这一刻起,事情变得有趣了:你点击播放,demux 线程开始往队列里塞 packet。塞多快?塞多少?什么时候该停下来?这些问题没有一个"标准答案"——每个播放器的答案都不一样,而 mpv 的答案是所有开源播放器里最精打细算的一个。

2026-09-05 06:50:26 317

原创 [mpv架构] (3) mpv 怎么实现 MP4 秒开?

当敲下 mpv video.mp4,回车。在第一个画面出现在屏幕上之前,mpv 已经做了一系列精密的初始化:打开文件、探测格式、创建 FFmpeg 上下文、解析轨道——这些在 demux 线程启动之前完成。选轨和建解码器则在 demux 线程启动之后、预读开始之前。你品品这个细节:mpv 甚至还没开始解码,就已经知道这个文件有几条视频轨、各自的分辨率和帧率、每条音轨的采样率。它是怎么在几百毫秒内完成这些判断的?

2026-08-29 16:18:23 448

原创 [mpv架构] (1) mpv的主循环到底在等什么?dispatch调度机制详解

几乎所有播放器都有一个"主循环"。OpenCV 用 `cv::waitKey(30)` 凑合;ffplay 把逻辑塞进 SDL 事件回调里。mpv 呢?你正看着视频,按一下空格暂停——**mpv 的 CPU 瞬间掉到接近 0%**,像一台熄火的发动机。可你再按一次空格,它又能瞬间恢复、逐帧精准地接着播。

2026-08-20 09:55:16 457

原创 [mpv架构] (2) mpv 为什么要把 FFmpeg 的 I/O 换掉?

用 mpv video.mp4 播放本地文件,中途按 q。退出几乎在瞬间完成——用户看到的是"快",但真正值得琢磨的是背后的设计问题:demux 线程可能正阻塞在 read() 或 recv() 上,播放器凭什么既能随时打断它,又能在平时不空转浪费 CPU?

2026-08-02 16:37:24 444

原创 [mpv脚本系统] (五) C层系统调用的实现: mpv client通信机制

上一篇文章把 `mp` 模块比作脚本的"操作系统",C 层的 `mp.get_property`、`mp.wait_event` 等函数就是"系统调用"。但系统调用本身怎么实现的?为什么 `mp.get_property("volume")` 能拿到播放器的音量?

2026-06-07 11:05:57 346

原创 [mpv脚本系统] (四) 脚本加载与事件循环系统

在 mpv 里写了一个 Lua 脚本,只需要 `mp.register_event("start-file", fn)`,播放新文件时 `fn` 就自动被调用。这背后,是 `mp` 模块提供的**一整套运行时环境**在默默运转。本文用"操作系统"类比,从设计层面讲清楚这套环境做了什么、怎么实现的。

2026-06-07 10:48:58 480

原创 [mpv脚本系统] (三) C 函数如何注册成 Lua 模块

你有没有好奇过:mpv 启动时,Lua 脚本里写 local utils = require("mp.utils") 就能拿到 readdir、split_path 这些 C 函数——这些函数是怎么从 C 侧注册到 Lua 侧的?require 又是怎么知道去哪个表里找的?

2026-06-03 00:36:54 459 2

原创 [mpv脚本系统] (二) Lua三层闭包实现自动资源管理

从一个疑惑开始:为什么 mpv 的 Lua 绑定函数(如 mp.utils.readdir)打开目录、分配临时内存后,从不写 closedir 或 free,却从不泄漏?

2026-06-02 09:00:00 437 1

原创 [mpv脚本系统] (一) Lua 闭包与上值 — 从概念到 C API

闭包不是"函数套函数"的语法糖。在 Lua 的 C API 中,它是函数实例 + 被捕获上值的运行时组合体——理解了这一点,才能看懂 mpv 那种"三层闭包自动管理资源"的精妙设计。本文用最小可运行的 C 代码,把闭包和上值在 C API 层的本质讲清楚,为后续 mpv 源码拆解打下基础。

2026-06-01 09:44:00 425

原创 MPV懒人配置与现代UI改造指南

先到处抄一堆参数再去猜为什么播放器打不开最后把“MPV 很难用”归因到软件本身先用本文把基础体验搭好。再理解idlekeep-opengeometry这些窗口行为。最后再进入vogpu-apihwdec、Lua 脚本、IPC 这些底层主题。这样学 MPV,不会乱,也更容易建立长期可维护的配置。下一步读什么?如果你现在已经把 MPV 配得顺手了,下一篇最适合读的是《Article_MPV_Pseudo_GUI与Idle机制剖析.md。

2026-05-19 09:51:46 508

原创 MPV全平台编译调试保姆级教程(Win/Mac篇)

万事开头难,把 MPV 从源码编译起来并在 IDE 中跑通断点,为我们提供了深入探究 MPV 渲染架构的透视镜,这也是掌握硬核音视频底层技术的第一步。在后续的文章中,我们将利用搭建好的调试环境,逐步拆解 MPV 从 Demuxer 到 Decoder,再到最终高阶 GPU 渲染流水线的全链路源码,敬请期待!

2026-05-14 09:12:46 431

原创 深入解析 ZLToolKit(5):function_safe

function_safe是解决C++回调函数重入修改问题的安全工具。当回调执行过程中需要修改自身时,普通std::function会导致未定义行为。function_safe采用延迟更新机制,通过双缓存策略(_impl执行区+_tmp暂存区)和状态标志(_doing+_update),利用RAII管理状态转换。其模板构造函数通过SFINAE技术避免与拷贝构造冲突,确保类型安全。该设计完美解决了网络编程中回调函数安全更新的需求,提升了异步程序的稳定性。

2026-01-03 13:51:55 1039

原创 C++ 内存模型与Memory Order深度解析

摘要:本文深入探讨了C++内存模型与Memory Order在多核处理器环境下的关键作用。从硬件层面分析了Store Buffer和Invalidate Queue导致的指令重排问题,详细解读了C++11提供的六种内存顺序语义及其硬件对应关系。通过SpinLock实现展示了acquire-release的典型应用模式,并以无锁队列为例,结合硬件交互流程图解构了内存屏障在多核间的同步机制。文章为高性能并发编程提供了从理论到实践的完整指导,特别适合需要编写无锁数据结构的开发者。

2025-12-17 17:45:59 1219

原创 深入解析 ZLToolKit(4): ResourcePool对象池

本文介绍了一个基于智能指针自定义删除器机制的高性能对象池ResourcePool。该对象池通过std::shared_ptr实现自动回收功能,当对象引用计数归零时不会直接删除内存,而是将对象归还给对象池。核心设计采用Handle-Body模式,ResourcePool作为对外接口类包装内部的ResourcePool_l实现类。ResourcePool_l使用vector存储空闲对象,配合自旋锁实现无锁竞争的高并发访问,遇到竞争时降级为直接分配/释放。智能指针shared_ptr_imp携带回收标志,支持中途

2025-12-12 18:28:21 781

原创 ZLToolKit模块(三) NoticeCenter(事件广播)

摘要: 本文详细解析了ZLToolKit中的NoticeCenter模块,其采用发布-订阅模式实现系统解耦,通过双层Hash Map结构(事件层+监听层)高效管理事件。核心类包括: EventDispatcher:处理特定事件的注册/触发,采用Copy-On-Write机制避免死锁,支持中断传播 NoticeCenter:单例入口,管理所有事件分发器 NoticeHelper:模板辅助类简化调用 关键设计: 类型擦除(Any类)支持任意参数回调 线程安全:递归锁+临界区外执行回调 tag机制(通常用this

2025-12-12 17:26:57 1054

原创 从move和forward到完美转发(深度 !!)

摘要:std::move和std::forward虽然底层都是static_cast,但行为差异显著。std::move通过remove_reference无条件转为右值引用,强制资源转移;而std::forward利用引用折叠规则,根据模板参数_Tp智能保留原始值类别(左值/右值)。前者用于明确移动场景,后者用于完美转发参数。理解这一区别是掌握现代C++移动语义的关键。

2025-12-12 11:23:04 735

原创 深入理解Lua闭包机制:从原理到mpv实战(深度!)

闭包 (Closure)是函数式编程的核心概念之一。在 Lua 中,闭包是一个函数实例与其**捕获的外部环境(上值)**的组合体。核心特征对比特性普通函数闭包访问范围参数 + 局部变量参数 + 局部变量 + 外部变量生命周期调用结束即销毁可以"记住"定义时的环境状态保持❌ 无状态✅ 可维护私有状态上值就是被闭包"捕获"的那些外部变量。在上面的例子中,count就是匿名函数的上值。当用创建一个 C 闭包时,栈顶的n个值会被"封装"进这个闭包,作为它的上值。在 C 函数fn。

2025-10-20 22:53:54 1014

原创 【C++/Lua联合开发】 (三) C++调用Lua

上篇讨论了 C 函数如何被 Lua 调用,反过来呢?C++ 程序如何读取 Lua 脚本里的变量、调用 Lua 函数、处理返回值?

2025-10-18 21:20:32 535

原创 【C++/Lua联合开发】 (二) Lua调用C++函数

本文从零开始,逐个讲解最常用的 C API 函数——每个函数做什么、怎么影响栈、在真实项目中怎么用(文中用 mpv 源码作为参考案例)。

2025-10-18 16:20:43 562

原创 【C++/Lua联合开发】 (一) Lua基础知识(数据类型)

Lua 是一种轻量级、高效的脚本语言,由巴西里约热内卢天主教大学(PUC-Rio)于1993年开发。它的名字在葡萄牙语中意为"月亮"。轻量级: 核心库非常小巧,完整的解释器只有几百KB高效: 执行速度在脚本语言中名列前茅,特别是使用 LuaJIT 时可嵌入: 设计初衷就是作为嵌入式脚本语言简洁语法: 语法简单清晰,易于学习动态类型: 弱类型语言,灵活但需注意类型安全垃圾回收: 自动内存管理协程支持: 内置协程机制,便于实现复杂的控制流。

2025-10-18 12:53:10 1162

原创 积加科技音视频一面

从底层实现、时间复杂度、内存使用、使用场景等角度对比。: 视频编码原理、H.264标准理解、多媒体技术基础。: 视频编码参数理解、QP与码率关系、实际编码经验。: I/O多路复用、Linux系统编程、高并发处理。: C++11内存模型、并发编程、底层系统理解。: C++内存模型、虚函数机制、面向对象原理。: 智能指针理解、多线程编程、C++11特性。: 数据结构理解、STL容器特性、性能分析。: 网络协议理解、拥塞控制算法、新技术认知。: 从实现机制、性能、使用限制等对比。

2025-09-24 19:52:25 1794

原创 理解现代C++ (七) 类的六大特殊函数(深度,体系化)

析构的平凡性影响所有构造的平凡性;其它五者的平凡性各自独立;要求除了默认构造之外的其它五者必须平凡;trivial则要求全部平凡。是在没有更多信息的前提下,也能保证拷贝安全。

2025-09-22 15:27:40 899 1

原创 理解现代C++ (六) 初始化(一文搞定)

无参数初始化有两种形式:值初始化(带有()或{})和默认初始化(无()或{}前者会保证进行初始化(调用默认构造,或清零,或混合);后者只会调用默认构造(如果是平凡的,则什么都不做)。有参数初始化,可以通过()或者{}的方式进行,两者的差异在于后者更优先匹配初始化列表,以及窄向转换的约束。在不使用()或者{}的场景下,使用进行的初始化,属于拷贝初始化。如果被初始化对象是一个class类型,copy构造或move构造会被调用;在使用()或{}的场景下,在C++ 17之后,除了explicit。

2025-09-22 09:30:00 1144

原创 理解现代C++ (五) auto类型推演(最全版本,一文学会)

auto类型推演脱胎于模版函数的类型推演,它们的能力几乎等价(除了初始化列表的情况)。这也就意味着,其实在C++11之前,C++早就具备了auto的能力,只是没有从语法上允许而已。

2025-09-20 14:18:30 1057

原创 理解现代C++ (四) decltype类型推演(最简单版本,一文掌握)

本文介绍了C++11引入的decltype特性,它能够推导表达式的类型,增强泛型编程能力。decltype有两种使用方式:带括号decltype((expr))和不带括号decltype(expr)。带括号时,根据表达式类别推导类型:纯右值对应非引用类型,泛左值对应引用类型(左值引用或右值引用)。不带括号时,除直接访问变量名会返回其定义类型外,其余情况与带括号一致。这种设计既满足获取变量原始类型的需要,也支持基于表达式类别的类型推导,为C++类型系统提供了更灵活的支持。

2025-09-18 19:07:58 587

原创 理解现代C++ (三) 右值引用(最通俗易懂的讲解)

理解现在C++,右值引用的产生和用法

2024-11-26 09:30:00 1003

原创 理解现代C++ (二) 引用

理解现在C++中的引用的用法

2024-11-22 09:27:35 946

原创 理解现代C++ (一) 值与对象(最通俗易懂的讲解)

理解现代C++之值与对象

2024-11-20 20:43:38 1375

原创 C++武器库之enable_shared_from_this

std::enable_shared_from_this 和 shared_from_this 为类的成员函数提供了一种安全获取自身 std::shared_ptr 的方法,特别适用于需要在异步操作、回调函数中延长对象生命周期的场景。合理使用它们可以有效避免内存管理问题,提高程序的健壮性。

2024-11-04 10:00:00 2414

原创 C++武器库之default成员函数

在C++11中引入的**=default员显式地请求编译器为类生成默认版本的特殊成员函数**。这些特殊成员函数包括默认构造函数、拷贝构造函数、移动构造函数、拷贝赋值运算符、移动赋值运算符以及析构函数。使用default可以让编译器根据语言规则自动生成这些函数的高效实现,而不是由程序员手动编写。

2024-11-01 09:15:00 698

原创 C++武器库之noncopyable类

noncopybale确保资源不可复制。

2024-10-30 09:30:00 710 1

原创 入门C++模板编程(二) 类模板

C++模板类,也称为类模板(Class Template),是C++中一种强大的泛型编程工具。它允许程序员定义一个通用的类蓝图,这个蓝图可以被实例化为处理不同数据类型的多个具体类。通过使用类模板,我们可以编写出更加灵活、可重用且高效的代码。

2024-10-29 09:30:00 1720

原创 入门C++模板编程(一) 函数模板

函数模板入门技巧

2024-10-25 12:47:20 659

原创 深入解析 ZLToolKit(3): NoticeCenter

ZLToolkit系列第二篇,消息广播模块。

2023-01-13 08:59:14 666

原创 深入解析 ZLToolKit(2):CMD命令行解析

ZLToolkit系列第二篇,命令解析模块。

2023-01-05 08:59:07 624

原创 深入解析 ZLToolKit(1): Logger日志

ZLToolkit的日志模块

2023-01-01 23:18:35 1172

原创 FFmepg使用D3D11va解码渲染,内存泄漏定位

ffmpeg

2022-06-24 17:07:37 1656 3

408计算机组成原理思维导图

408计算机组成原理思维导图,考研预习复习,知识点一网打尽。 PS: 配合王道辅导书使用效果更佳。

2025-09-20

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除