• C++ Lambda 本质 & 变量捕获

    C++ 11 引入 lambda 之后,可以很方便地在 C++ 中使用匿名函数,这篇文章主要聊聊其背后的实现原理以及有反直觉的变量捕获机制。在阅读本文之前,需要读者对 C++ lambda 有一个简单的了解。

    C++ Lambda 的函数结构

    1
    [capture_list](parameter_list) -> return_type {function_body}

    其中,capture_list 表示捕获列表,parameter_list 表示函数参数列表,return_type 表示函数返回类型,function_body 表示函数体。下面是一个简单的 Lambda 函数示例,这里定义一个计算面积的名为 area 的 lambda。

  • std::shared_ptr 的线程安全性 & 在多线程中的使用注意事项

    我们在讨论 std::shared_ptr 线程安全时,讨论的是什么?在讨论之前,我们先理清楚这样的一个简单但却容易混淆的逻辑。 std::shared_ptr 是个类模版,无法孤立存在的,因此实际使用中,我们都是使用他的具体模版类。这里使用 std::shared_ptr 来举例,我们讨论的时候,其实上是在讨论 std::shared_ptr 的线程安全性,并不是 SomeType 的线程...
  • C++ std::enable_shared_from_this<T> 具体实现

    C++ 中使用 std::shared_ptr 智能指针不当有可能会造成循环引用,因为 std::shared_ptr 内部是基于引用计数来实现的, 当引用计数为 0 时,就会释放内部持有的裸指针。但是当 a 持有 b, b 也持有 a 时,相当于 a 和 b 的引用计数都至少为 1,因此得不到释放,RAII 此时也无能为力。这时就需要使用 weak_ptr 来打破循环引用。

    通过 weak_ptr 来避免循环引用

    来看一个比较典型的 delegate / observer 的场景:

  • AArch64 学习 (二) 函数调用 (Function Call Convention)

    本系列的第一篇 中介绍了 AArch64 的基础指令、进程内存布局以及基础栈操作 等. 本文该系列的第二篇, 主要聊聊函数调用, 涉及到的就是 Function Call Convention. 初衷还是尽可能 “浅入深出” 地 got 到语言背后的本质, 这不是一个手册, 所以不是完备的.

    1. 我们在聊函数调用的时候在聊什么?

    至少我们应该把函数调用的几个问题搞清楚:

    1. 函数在汇编层是怎么调用的, 本质是什么?
    2. 函数的参数怎么传?
    3. 返回值写到哪里? 怎么传给 caller?
    4. 调用完之后, 怎么返回到原来的位置?

    Function Call Convention 其实就是回答这些问题的, 接下里我们一一找到答案.

    1.1. 函数调用本质是什么?

  • AArch64 学习 (一) 基础指令, 内存布局, 以及基础栈操作

    1. 什么是 ARM?

    正式开始之前, 我们先来了解一下什么是 ARM, 以及对应的一些概念.

    Wikipedia 上是这么介绍 ARM 的:

    ARM (stylised in lowercase as arm, formerly an acronym for Advanced RISC Machines and originally Acorn RISC Machine) is a family of reduced instruction set computer (RISC) instruction set architectures for computer processors, configured for various environments.

    ARM 是 高级 - RISC (精简指令集)- 机器 的缩写, 是精简指令集架构的家族. 同时 Arm Ltd. 也是开发和设计、授权这项技术的公司名称.

    1.1. 有哪些指令集架构呢? (TRDR, 可跳过)

    目前用的比较多的架构是 ARMv7 和 ARMv8, 这两个名字各自都是一个系列.

    在 ARMv7 以及之前都是最多支持 32 位架构 (更早还有 16 位, 甚至更低), 那么 32 位架构对应的 ISA 也就是指令集称为 A32. 32 位下指令的地址空间最大只有 4GB, 苹果系列的代表是 iPhone 4 使用的 A4 芯片, 以及 iPhone 4s 使用的 A5 芯片.

  • 深入理解 AudioUnit (二) ~ Mixing Unit & Effect Unit & Converter Unit

    本系列的 第一篇 中介绍到了 AudioUnit 中和系统硬件交互的 IO Unit, 以及如何使用它进行音频的采集和播放. 本文是该系列的第二篇, 将会介绍 AudioUnit 中另外 四类 非常重要的 AudioUnit: MixingEffect UnitConverter Unit 以及 Generator Unit.

    1. Mixing Unit

    Mixing unit 在实际场景中非常的实用, 特别我们需要对多路音频做处理或者播放. 比如对于音频制作 app 来做, 通常要支持混入 N 多种乐器的声音和片段, 比如 吉他、钢琴、贝斯、人声、和声等等. 这个时候使用 Mixing unit 把这些 input bus 混成一路 output 交给 IO Unit 播放, 就是一个很必要且自然的结果.

  • 深入理解 AudioUnit (一) ~ IO Unit 结构和运行机制

    Apple 平台上如果涉及到音频采集, 很难避开 AudioUnit 这个工具库, AudioUnit 是 Audio Toolbox 下的一套有年头的 C API, 功能相对也比较强大, 虽然苹果最近几年推出并逐渐在其基础之后完善了一套 AVAudioUnit 的 OC / Swift 的 API, 但 AudioUnit 依然有很广泛的使用, 而且了解这套 C API 也对理解 AVAudioUnit 内部的实现和使用有很大的帮助.

    其实里面的概念并不是特别复杂, 但是因为文档比较老旧, 概念也比较绕, 上手并不易. 我此前做唱歌和直播 app 相关的工作, 对 AudioUnit 使用的也比较多, 积累了一些经验, 希望能够最大程度地把一些通用的概念和使用方法分享出来. 接下来将带大家剖析 AudioUnit 的内部原理和丰富多样的使用方式, 如果你在做涉及到声音采集和处理的工作, 希望能带大家深入浅出地摸透 AudioUnit.

    关于 AudioUnit 的文章是一个系列, 我希望能够把之前的经验结合一些实际的场景来介绍, 大概分为以下四个部分:

  • 函数指针、函数对象、lambda 表达式、std::function

    1. 函数指针

    函数指针 (Function Pointer) 就是指向函数地址的指针

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int Sum(int a, int b) {
    return a + b;
    }

    typedef int(*SumFunc)(int x, int y);

    // --------

    SumFunc sum = Sum;
    std::cout << sum(1, 2) << std::endl;
  • WWDC 21 - 探索使用 VideoToolbox 进行低延迟视频编码

    低延迟编码对于很多视频 app 来说都很重要,特别是对实时音视频场景。苹果在 WWDC 2021 在 VideoToolbox 里推出了一种新的低延迟编码模式。低延迟编码模式的主要目的是为实时通讯场景优化现有的编码流程。

    低延迟视频编码有以下的特点,从而对一个实时视频通讯 app 进行优化。

  • WWDC 21 - 使用 AVQT 评估视频质量

    REF: WWDC 2021 - Evaluate videos whith the Advanced Video Quality Tool

    AVQTAdvanced Video Quality Tool 的缩写,是苹果在 WWDC 21 上推出的一款评估 ** 视频感知质量 ** 的工具。


    一、背景介绍(非 WWDC 内容)

    1.1 视频质量评估的现状

    在正式开始之前,我想跟大家科普几个概念和行业现状,这些对理解本次的内容很有帮助。

    视频质量评估是个老话题了,主流的分为下面几类:

    1. 主观评测,也就是人工评估,准确率高,但成本大,难规模化
    2. 客观评测,纯依靠算法,比如PSNR(Peak Signal-to-Noise Ratio 峰值信噪比),SSIM(Structural SIMilarity 结构相似性),准确率低,成本小,容易规模化
    3. 感知质量评测,代表是 Netflix 的VMAF,VMAF 是基于机器学习算法,根据人工的识别结果训练模型,目的是要模拟真人评测,结果上达到接近人工评估的准确度,这也是 “感知” 一词的含义。优点是准确率高,也容易规模化。我们今天要聊的 AVQT 也属于此类。

    还有一种分类是有源评估无源评估,有源评估顾名思义,需要有参考源,比如有一个未压缩的超清 Raw 视频,它作为参考源,然后在进行处理编码之后,变成一个低分辨率、低码率的的视频,这个作为评估的对象,对比参考源视频,打出分数。感知质量评测的工具都属于有源评估范畴,即需要参考源来进行评估打分。

12346