- 博客(184)
- 资源 (17)
- 问答 (1)
- 收藏
- 关注

原创 测试驱动开发(TDD)实践与技巧
引言测试驱动开发,英文全称 Test-Driven Development,简称 TDD,是一种不同于传统软件开发流程的开发方法。在《程序员的职业素养》第五章,我第一次看到有关 TDD 内容,当时Bob大叔向我展示了一种不可思议的编程开发方法,这种方法颠覆了我的认知。Bob 大叔列举了 TDD 很多好处,例如确定性、降低代码缺陷、方便代码重构、测试单元文档化,更优秀的代码设计等等。并强力安利读者们尝试 TDD,因为 TDD 是专业人士的选择。在 Bob 大叔的洗脑下,我决定去尝试学习如何使用 TDD。
2021-06-11 09:34:47
12392
3
原创 GStreamer 简明教程(九):插件开发,以一个音频特效插件为例
GStreamer 简明教程系列已经更新了 9 期,这些教程基本是我个人在学习官方教程中的一些理解和总结。官方的基础教程中远不止 9 期,但后续的基础教程我决定不再更新了,因为后面的内容基本还是围绕如何使用 GStreamer 中的某种功能来展开的,它不涉及 GStreamer 底层代码的实现逻辑。回看我最初学习 GStreamer 的目的,最重要是掌握 GStreamer 的设计思想,学习消化后以便自己能设计出一套类似的音视频框架,因此我对 GStreamer 底层的实现逻辑更感兴趣。
2025-01-21 18:43:12
1429
原创 GObject 简明教程(二)
最近,我一直在深入学习 GStreamer(相关教程可以从我主页中看到)。在探索其复杂的设计逻辑时,我意识到需要深入研究 GStreamer 的源码。而因为 GStreamer 是基于 GObject 开发的,掌握 GObject 的基本概念就显得尤为重要。本文整理自,简化了细节,保留了一些关键内容,以便更好地理解。上一章GObject 简明教程(一)我们介绍了的前面五章。今天我们继续,将后面几章也进行总结和更新。
2025-01-07 19:21:52
646
原创 GObject 简明教程(一)
最近,我一直在深入学习 GStreamer(相关教程可以从我主页中看到)。在探索其复杂的设计逻辑时,我意识到需要深入研究 GStreamer 的源码。而因为 GStreamer 是基于 GObject 开发的,掌握 GObject 的基本概念就显得尤为重要。本文整理自,简化了细节,保留了一些关键内容,以便更好地理解。提示:以下是本篇文章正文内容,下面案例可供参考。
2024-12-21 19:04:14
1336
4
原创 GStreamer 简明教程(九):Seek 与跳帧
本文对内容进行说明,重点是理解 GStreamer 中 seek events 和 step events。
2024-11-16 22:26:12
925
原创 GStreamer 简明教程(八):常用工具介绍
本章内容是对 GStreamer 官方教程中第九、十和十一三章的一个介绍。这几章涉及的代码不多,主要是介绍 GStreamer 中工具,包括 GstDiscoverer、gst-discoverer-1.0、gst-launch-1.0、gst-inspect-1.0 、日志工具等。这块可以扩展的内容比较少,但我又不想漏了这块,因此本文只是做一些粗粒度的总结。
2024-11-08 10:00:29
1209
1
原创 GStreamer 简明教程(七):实现管道的动态数据流
本章基于进行说明和补充,以便读者掌握如何动态的插入或者提取出 Pipeline 中的数据。本章内容并不复杂,它引入了两个新的 Element:appsrc 和 appsink。通过这两个 Element 我们可以实现动态管理数据流。由于官方教程代码在本人机器上总是运行失败,因此我对它做了一些修改,具体代码在本文介绍了 appsrc 和 appsink 的使用,通过使用 Element Signals 和 Element Actions 机制,我们可以动态地与元素进行交互。
2024-10-16 21:25:08
1534
原创 GStreamer 简明教程(六):利用 Tee 复制流数据,巧用 Queue 实现多线程
本章基于官方教程进行说明和补充。本章内容并不复杂,引入了两个新的 Element:Tee 和 Queue。Tee 用于复制数据, Queue 创建线程让 Pipeline 的一部分在另外线程中运行。由于官方教程在本人机器上总是无法运行,我对它做了一些修改,具体代码在。
2024-10-12 17:59:53
1309
原创 GStreamer 简明教程(五):Pad 相关概念介绍,Pad Capabilities/Templates
本章基于官方教程进行一些说明和补充。本来想对进行讨论的,但我的机器上安装 gtk 后运行程序总是崩溃,因此放弃。在前面的章节中也有泛泛地提到过 Pad,例如GStreamer 简明教程(二):基本概念介绍,Element 和 Pipeline和GStreamer 简明教程(三):动态调整 Pipeline。接下来这一章,我们将对 Pad 这个在 GStreamer 中非常重要的概念进行详细阐述。在 GStreamer 中,Pad 是连接不同元素之间的接口,允许它们相互通信和传递数据的概念。
2024-08-25 21:31:22
1074
原创 GStreamer 简明教程(四):Seek 以及获取文件时长
如何查询 Pipeline 的信息,例如时长,当前播放位置等如何进行 seek 操作。
2024-08-21 20:15:12
1177
原创 GStreamer 简明教程(三):动态调整 Pipeline
本章来了解 GStreamer 动态调整 Pipeline 的流程,这章代码略长,略微有些复杂,各位看官稍稍耐心些。在src参数表示触发信号的 GstElement,在本例中通常为 uridecodebin,因为它是唯一附加了该信号的元素。信号处理函数的第一个参数始终是触发信号的对象。new_pad参数表示刚刚添加到src元素的 GstPad。通常,我们希望连接的就是这个 pad。第一次,添加的 pad 负责输出视频数据第二次,添加的 pad 负责输出音频数据data。
2024-08-17 15:10:00
1298
原创 GStreamer 简明教程(二):基本概念介绍,Element 和 Pipeline
在上一章中我们成功的搭建了 GStreamer 的调试环境,并运行了 Hello World 程序。本章我们将介绍 GStreamer 中的基本概念,包括 Element 和 Pipeline。另外,还介绍使用 gst-inspect-1.0 程序来查看插件的基本信息。GStreamer 是基于插件的架构,它处处离不开插件,你几乎所有功能都是被封装在插件之中。因此如何查询插件信息是我们需要掌握的。
2024-08-13 21:34:47
1818
原创 GStreamer 简明教程(一):环境搭建,运行 Basic Tutorial 1 Hello world!
本系列文章将纪录学习 [GStreamer] 的过程。多媒体处理是一个复杂的任务,[GStreamer] 的管道架构可以将复杂的任务以「图」的形式模块化的进行处理,它足够灵活。学习 [GStreamer] 这种架构思想,可以帮助我扩展视野,面对复杂任务如何给出一套灵活可靠的框架。掌握 [GStreamer] 对求职有所帮助,如果你对 [GStreamer] 很熟悉,很多音视频岗位是可以加分的。
2024-08-09 22:09:56
1986
原创 LearnOpenGL - Android OpenGL ES 3.0 多线程同步,fence、glWaitSync 和 glClientWaitSync 的运用
本章讨论 OpenGL ES 中多线程技术的运用。首先,说明我们为什么需要这项技术,在 ARM OpenGL ES 教程中提到当我们转向更复杂的图形应用程序时,可能会想要使用多线程(MT)。一个典型的情况是,我们的图形应用程序需要执行大量的数学运算。在这种情况下,可能通过将工作量移至不同于管理图形操作的线程来提高性能。另一个常见的例子是我们想让图形用户界面(GUI)在一个独立的线程中运行。多线程的好处非常重要。MT使得我们的应用程序始终保持响应,并且不只是与应用程序的GUI有关。
2024-07-21 22:01:56
1639
原创 LearnOpenGL - Android OpenGL ES 3.0 基础特效实现
本章我们学习下如何来写一个基础特效,本文所有代码你可以在找到本文介绍了 8 中基础特效的实现逻辑,所有代码可以在找到。
2024-07-12 10:16:58
1476
原创 LearnOpenGL - Android OpenGL ES 3.0 使用 FBO 进行离屏渲染
利用 FBO(Framebuffer Object),我们可以实现离屏渲染。在前面的章节中,当我们调用 glDrawElements 后,手机屏幕上就会显示出绘制的图像。这意味着 OpenGL 将数据直接渲染到了手机屏幕上。通过使用 FBO,我们可以将数据渲染到纹理上,而不是直接渲染到屏幕,这个过程称为离屏渲染。通过离屏渲染,我们可以在最终显示之前对图像进行复杂的处理。这种方法非常有用,比如在后期处理效果(如模糊、HDR、阴影等)中,或者在渲染多个场景以进行纹理贴图、环境映射等操作时。
2024-06-27 18:30:32
2153
1
原创 LearnOpenGL - Android OpenGL ES 3.0 YUV 渲染
在上一章LearnOpenGL - Android OpenGL ES 3.0 绘制纹理中,我们详细地解释了顶点着色器到片元着色器之间的工作流程,并向你展示了如何绘制一张纹理。本章节我们将讨论如何使用 OpenGL ES 来将一张 YUV 格式的图片转换为 RGB,并渲染在屏幕上。本文所有代码可以在和找到这部分推荐看之前写的YUV 文件读取、显示、缩放、裁剪等操作教程,这次不再赘述。需要重点理解不同 YUV 格式之间的数据排列方式。
2024-06-25 21:36:11
1406
2
原创 LearnOpenGL - Android OpenGL ES 3.0 绘制纹理
在LearnOpenGL - Android OpenGL ES 3.0 绘制三角形中我们学会了如何在 Android 下搭建 GLES 环境,并绘制三角形。本文我们将讨论如何绘制纹理。本文代码在顶点着色器: 执行次数与顶点数量相同,每个顶点执行一次。片元着色器: 执行次数与片元(像素)数量相同,每个片元执行一次。因此,片元着色器的执行次数通常远多于顶点着色器的执行次数,因为片元数量通常大于顶点数量。具体执行次数取决于渲染的几何图形在屏幕上的覆盖范围。
2024-06-21 10:05:14
1022
原创 GStreamer 源码编译,在 Clion 下搭建调试环境
最近在学习 GStreamer,官方提供了一些,本人希望能够断点调试,以便学习代码逻辑。本文记录如何在 Clion 搭建 GStreamer 源码编译、调试环境。
2024-06-15 17:52:01
739
原创 Android MediaCodec 简明教程(九):使用 MediaCodec 解码到纹理,使用 OpenGL ES 进行处理,并编码为 MP4 文件
在上一章节,我们已经探讨了如何使用 OpenGL ES 处理解码后的纹理,将彩色画面转换为灰色画面,并在 GLSurfaceView 上展示。在本章节,我们将研究如何将处理后的视频帧保存为本地的 MP4 文件。本文所有代码可以在找到。
2024-05-31 22:09:27
2566
2
原创 Matrix Profile,时间序列分析的强有力工具
介绍了一种分析时间序列的方法 Matrix Profile,具有简单性、易用性、普适性等优点,另外介绍了MP的具体应用,展示了如何利用MP去分析时间序列。
2024-05-30 21:26:08
984
原创 Android MediaCodec 简明教程(八):使用 MediaCodec 解码到纹理,使用 OpenGL ES 进行处理并显示在 GLSurfaceView 上
在之前的教程中,我们已经学习了如何使用 MediaCodec 解码视频到 OES 纹理。在这篇文章中,我们将进一步探讨如何使用 OpenGL ES 将彩色图像转换为灰色图像,并在 GLSurfaceView 上显示。本文所有代码你可以在中找到。
2024-05-19 20:18:53
1465
1
原创 Android MediaCodec 简明教程(七):使用 MediaCodec 解码到 OES 纹理上
在这个系列的第七章中,我们将深入探讨一些更复杂的知识点:如何将视频帧解码到OES纹理上。在前几章中,我们已经学习了如何查询MediaCodec信息,以及如何使用MediaCodec进行解码和编码。首先,我们需要理解为什么我们需要将视频帧解码到纹理上。Android MediaCodec 简明教程(四):使用 MediaCodec 将视频解码到 Surface,并使用 SurfaceView 播放视频,我们直接将视频帧解码到SurfaceView上进行播放,这种方法并没有对视频帧进行任何处理。
2024-05-09 21:54:11
1834
1
原创 Android MediaCodec 简明教程(六):使用 EGL 和 OpenGL 绘制图像到 Surface 上,并通过 MediaCodec 编码 Surface 数据,并保存到 MP4 文件
本博客介绍了使用Surface进行高效的MediaCodec视频编码技术。与ByteBuffer编码相比,Surface编码能更好地利用硬件加速,提升性能。文章首先概述了Surface编码流程,即通过MediaCodec提供的Surface绘制图像,然后编码器提取像素信息进行编码。接着,文章详细说明了使用Canvas在Surface上绘制图像的基本方法,包括创建编码器、获取Surface,并在一个循环中提交图像数据给MediaCodec。此外,还探讨了结合EGL和OpenGL进行高效图像渲染的高级方法,这种
2024-03-18 10:39:24
3042
原创 Android MediaCodec 简明教程(五):使用 MediaCodec 编码 ByteBuffer 数据,并保存为 MP4 文件
前面我们了解了 MediaCodec 解码的具体使用流程,包括异步和同步模式、解码到 ByteBuffers 或者 Surface。本章开始,我们将开始学习如何使用 MediaCodec 进行编码。与解码类似,MediaCodec 编码的输入支持 ByteBuffer 或者 Surface。遵循循序渐进的原则,我们从最简单的一种情况开始讲起:MediaCodec 编码过程中,输入的图像数据存放在 ByteBuffer 中。
2024-03-04 16:37:10
6148
原创 盲水印、暗水印(Blind Watermark)算法简明教程:算法原理、流程以及基于C/C++ 的代码实现
盲水印(blind watermark)算法是一种将数字水印嵌入到数字媒体中的技术,而不需要原始媒体文件。与传统的数字水印技术不同,盲水印算法不需要原始媒体文件来提取数字水印,因此更加安全和隐私保护。盲水印算法的基本原理是将数字水印嵌入到数字媒体的频域或空域中,使得数字水印能够在不影响原始媒体质量的情况下被提取出来。盲水印算法通常包括两个主要步骤:嵌入和提取。在嵌入阶段,数字水印被嵌入到数字媒体中。这通常涉及到将数字水印转换为频域或空域信号,并将其嵌入到数字媒体中。
2024-02-21 18:16:26
11255
4
原创 Android MediaCodec 简明教程(四):使用 MediaCodec 将视频解码到 Surface,并使用 SurfaceView 播放视频
在上一个教程Android MediaCodec 简明教程(三)中,我们学会了使用 MediaCodec 解码到 ByteBuffers 上,包括同步模式和异步模式。本章将讨论 MediaCodec 解码到 Surface 的相关知识点。Google 推荐使用 Surface 进行编解码操作,这样效率更高。
2024-01-29 16:48:37
4848
1
原创 C/C++ 静态代码检测工具 Clang-tidy 简易教程:安装、使用、配合 cmake 使用、加入 CI/CD 流程等
最近尝试将 Clang-tidy 加入到项目中,以便加强代码规范。本文纪录在这一过程中积累的关于 Clang-tidy 的知识,涵盖安装、使用、cmake 和 CI/CD 实践等内容。
2024-01-24 14:58:52
8471
原创 Android MediaCodec教程(三):详解如何在同步与异步模式下,使用MediaCodec将视频解码到ByteBuffers,并在ImageView上展示
在前两章中,我们已经对如何查询 Codec 和 Codec 的支持特性有了深入的理解,这是通过学习 MediaCodecList 和 MediaCodecInfo.CodecCapabilities 实现的。在确认设备的 Codec 支持特定视频后,我们可以创建相应的 MediaCodec 进行视频解码。本章,我们将探讨如何使用 MediaCodec 进行视频解码。MediaCodec 支持同步和异步两种模式,同时也支持使用 Surface 或 ByteBuffers 进行数据处理。
2024-01-19 10:32:22
4285
原创 Android MediaCodec 简明教程(二):使用 MediaCodecInfo.CodecCapabilities 查询 Codec 支持的宽高,颜色空间等能力
在上一章Android MediaCodec 简明教程(一)我们学习了如何使用 MediaCodecList 查询本机支持的 Codec 信息。= NULL) {本章将介绍类,它是 Android 音视频任务中非常有用的工具类。通过该类,我们可以查询 codec 的能力,包括支持的宽高、颜色空间、Profile 等信息。这些信息对于选择合适的 Codec 来解码或编码视频文件非常重要,也可以帮助我们发现某些特殊格式 Android 机器无法支持的情况,从而采用其他方案,如 FFmpeg 等。
2024-01-12 14:17:43
2657
原创 Android MediaCodec 简明教程(一):使用 MediaCodecList 查询 Codec 信息,并创建 MediaCodec 编解码器
最近在学习 Android MediaCodec 相关的知识,准备开个新坑把学习过程记录下来,总结成 MediaCodec 教程。在介绍 MediaCodec 编解码之前,让我们学习一些其他与之配套的组件,今天要讲的是。提示:以下是本篇文章正文内容,下面案例可供参考本文介绍了 MediaCodecList 的基本使用方法,并展示了如何使用 MediaCodecList 来创建 MediaCodec 编解码器。
2024-01-08 10:10:48
4351
原创 在 Android 上使用 MediaExtractor 和 MediaMuxer 提取视频\提取音频\转封装\添加音频等操作
之前我们介绍了 FFmpeg 并利用它解封装、编解码的能力完成了一款简易的视频播放器。额外的 so 文件。你需要将多个 so 文件集成至你的 app 中,使得 app 整体体积增加。额外的复杂性。这里的复杂性包括多个方面:集成的复杂性。为了引入 ffmpeg,你在编译脚本需要额外对这些库进行维护;此外,通常你不需要 FFmpeg 的全部能力,因此在编译 FFmpeg 库时你需要对其进行裁剪,这部分也需要额外的付出。编程的复杂性。
2024-01-02 17:34:48
3620
1
原创 基于 FFmpeg 的跨平台视频播放器简明教程(十二):Android SurfaceView 显示图片和播放视频
上一章中我们介绍了一个简易的播放器架构,对之前零碎的代码片段进行了组织和重构,形成了较为灵活的一种架构设计,它非常简单,但足够满足我们的需求。现在,接着我们在 Android 上的旅程。今天我们来讨论如何在 Android 上显示画面。Android 原生的 Java/Kotlin 接口播放视频还是很容易的,有 MediaController、MediaPlayer 等类可以直接使用,相关教程参考Android实现视频播放的3种实现方式。
2023-12-22 15:46:47
1003
原创 基于 FFmpeg 的跨平台视频播放器简明教程(十一):一种简易播放器的架构介绍
视频解码音频解码视频画面输出音频播放图像格式转换音频重采样音画同步经过前九章的学习,我们已经对以上模块有了深入的理解和实践。然而,目前的代码实现较为零散,缺乏统一的组织和抽象。接下来,我们将进入移动端播放器的设计与开发阶段。为了能够最大限度地复用现有的模块和代码,我们需要对现有的代码进行整理和优化,形成一种有效的架构。本文将介绍一种简单但实用的架构,它能够满足我们的需求。这种架构虽然简单,但是能够满足我们的需求。Decoder,负责解码音视频数据。
2023-11-20 09:57:16
738
原创 基于 FFmpeg 的跨平台视频播放器简明教程(十):在 Android 运行 FFmpeg
在前九章的学习中,我们已经成功地实现了一个基础的播放器,它拥有视频播放、音画同步、快进/快退等基本功能。当然,这个简易的示例还有许多可以优化的地方,比如添加更美观的用户界面,或者增加字幕功能等。然而,这并不是本教程的主要关注点。本系列文章更关注于跨平台播放器框架的构建,特别是在移动端。因此,从本章开始,我们将把重点转向 Android 端播放器的开发。前置知识包括一些 Android 的基本开发,以及 JNI 开发等。这些前置知识默认你有所了解,本文不会涉及。关于 JNI 可以参考笔者之前写的。
2023-10-26 21:56:45
1485
原创 基于 FFmpeg 的跨平台视频播放器简明教程(九):Seek 策略
经过前面八章的学习与代码实现,我们的播放器已经能够正常播放视频了,接下来我们将加入最常用的 seek 能力,让你能够快进/快退。本文参考文章来自。这个系列对新手较为友好,但 2015 后就不再更新了,以至于文章中的 ffmpeg api 已经被弃用了。幸运的是,有人对该教程的代码进行重写,使用了较新的 api,你可以在找到这些代码。本文的代码在和。本文介绍了播放器中如何实现快进、快退功能,并给出了具体的实现代码,还讨论了如何实现精准 seek 逻辑,并在最后给出了一些优化的思路。本文的代码在和。
2023-10-20 10:27:53
1947
2
原创 基于 FFmpeg 的跨平台视频播放器简明教程(八):音画同步
本文介绍了如何实现播放器的音画同步,首先介绍了 I/P/B 帧的区别,引出了 PTS 和 DTS 的概念;接着,介绍了在 FFmpeg 中的 timebase 的概念,让读者了解 FFmpeg 是如何描述时间的;然后,我们详细的描述了音画同步实施的具体要点,包括如何精确的纪录不同流的当前时间,在什么时间节点来更新时钟,以及音画同步的具体算法。
2023-08-09 21:23:08
1982
1
原创 基于 FFmpeg 的跨平台视频播放器简明教程(七):使用多线程解码视频和音频
在上篇文章中基于 FFmpeg 的跨平台视频播放器简明教程(六):使用 SDL 播放音频和视频,我们能够同时播放画面和音频。其中 SDL 启动了一个音频线程,每次需要音频数据时都会回调到我们定义的函数。现在,我们需要对视频显示做同样的事情。这么做能让我们的代码更加模块化,更容易使用。本文参考文章来自。这个系列对新手较为友好,但 2015 后就不再更新了,以至于文章中的 ffmpeg api 已经被弃用了。幸运的是,有人对该教程的代码进行重写,使用了较新的 api,你可以在找到这些代码。本文的代码在。
2023-07-28 21:29:51
1532
原创 基于 FFmpeg 的跨平台视频播放器简明教程(六):使用 SDL 播放音频和视频
在上篇文章基于 FFmpeg 的跨平台视频播放器简明教程(五):使用 SDL 播放视频中,我们使用 FFmpeg + SDL 来播放视频画面,但仅仅只是画面。今天,我们将讨论如何使用 FFmpeg + SDL 同时播放画面和声音。本文参考文章来自。这个系列对新手较为友好,但 2015 后就不再更新了,以至于文章中的 ffmpeg api 已经被弃用了。幸运的是,有人对该教程的代码进行重写,使用了较新的 api,你可以在找到这些代码。本文的代码在。
2023-07-10 21:21:00
1810
原创 基于 FFmpeg 的跨平台视频播放器简明教程(五):使用 SDL 播放视频
经过前面四章的学习,现在我们已经掌握了如何使用 FFmpeg 进行视频解码,中间穿插了很多音视频相关的知识点,例如容器、编解码器、解封装、像素格式、格式转换等等。现在回看,音视频的入门门槛还是比较高的,一个最简单的任务就已经涉及到大量的知识点。但问题不大,本人希望通过一系列的文章来带你入门,通过完成一个播放器项目来不断地学习音视频内容。,用于解封装相关的任务,用于解码相关的任务,用于 AVFrame 格式转换这些类的使用方式,你可以在单元测试中找到示例,此处不再赘述。资源管理。
2023-07-04 21:36:31
1856
CVC-ClinicSpec
2020-12-07
Introduction of RBF
2018-11-06
Zint 开发手册 Zint 开发手册
2018-08-14
AGCWD Code
2017-11-29
Pandas_Dummy_Variable
2017-10-16
CVPR12_SAS_code
2017-04-08
rtaudio学习Demo
2015-09-08
对录音进行变速和变调处理
2015-08-21
用mfc做桌面图标小广告
2016-03-24
TA创建的收藏夹 TA关注的收藏夹
TA关注的人