
音视频
文章平均质量分 94
芥末的无奈
这个作者很懒,什么都没留下…
展开
-
GStreamer 简明教程(十一):插件开发,以一个音频生成(Audio Source)插件为例
GStreamer 中插件分为三种:Source、Filter 和 Sink,在上一章中我们学习了如何写一个 Filter 插件,可以说 Filter 插件是最简单的,因为它只需要关系数据的处理逻辑,而 Source 和 Sink 就更加复杂一些。本章我们来讨论如何写一个 Source 插件。本章所提及的代码你可以在my_plugin找到。以上,我们就将 AudioSource 如何生成数据的逻辑大致讲了一遍,运行之后可以听到正弦波的声音。原创 2025-04-25 22:34:51 · 1222 阅读 · 0 评论 -
GStreamer 简明教程(十):插件开发,以一个音频特效插件为例
GStreamer 简明教程系列已经更新了 9 期,这些教程基本是我个人在学习官方教程中的一些理解和总结。官方的基础教程中远不止 9 期,但后续的基础教程我决定不再更新了,因为后面的内容基本还是围绕如何使用 GStreamer 中的某种功能来展开的,它不涉及 GStreamer 底层代码的实现逻辑。回看我最初学习 GStreamer 的目的,最重要是掌握 GStreamer 的设计思想,学习消化后以便自己能设计出一套类似的音视频框架,因此我对 GStreamer 底层的实现逻辑更感兴趣。原创 2025-01-21 18:43:12 · 1540 阅读 · 0 评论 -
GObject 简明教程(二)
最近,我一直在深入学习 GStreamer(相关教程可以从我主页中看到)。在探索其复杂的设计逻辑时,我意识到需要深入研究 GStreamer 的源码。而因为 GStreamer 是基于 GObject 开发的,掌握 GObject 的基本概念就显得尤为重要。本文整理自,简化了细节,保留了一些关键内容,以便更好地理解。上一章GObject 简明教程(一)我们介绍了的前面五章。今天我们继续,将后面几章也进行总结和更新。原创 2025-01-07 19:21:52 · 696 阅读 · 0 评论 -
GStreamer 简明教程(九):Seek 与跳帧
本文对内容进行说明,重点是理解 GStreamer 中 seek events 和 step events。原创 2024-11-16 22:26:12 · 996 阅读 · 0 评论 -
GStreamer 简明教程(八):常用工具介绍
本章内容是对 GStreamer 官方教程中第九、十和十一三章的一个介绍。这几章涉及的代码不多,主要是介绍 GStreamer 中工具,包括 GstDiscoverer、gst-discoverer-1.0、gst-launch-1.0、gst-inspect-1.0 、日志工具等。这块可以扩展的内容比较少,但我又不想漏了这块,因此本文只是做一些粗粒度的总结。原创 2024-11-08 10:00:29 · 1310 阅读 · 0 评论 -
GStreamer 简明教程(七):实现管道的动态数据流
本章基于进行说明和补充,以便读者掌握如何动态的插入或者提取出 Pipeline 中的数据。本章内容并不复杂,它引入了两个新的 Element:appsrc 和 appsink。通过这两个 Element 我们可以实现动态管理数据流。由于官方教程代码在本人机器上总是运行失败,因此我对它做了一些修改,具体代码在本文介绍了 appsrc 和 appsink 的使用,通过使用 Element Signals 和 Element Actions 机制,我们可以动态地与元素进行交互。原创 2024-10-16 21:25:08 · 1634 阅读 · 0 评论 -
GStreamer 简明教程(六):利用 Tee 复制流数据,巧用 Queue 实现多线程
本章基于官方教程进行说明和补充。本章内容并不复杂,引入了两个新的 Element:Tee 和 Queue。Tee 用于复制数据, Queue 创建线程让 Pipeline 的一部分在另外线程中运行。由于官方教程在本人机器上总是无法运行,我对它做了一些修改,具体代码在。原创 2024-10-12 17:59:53 · 1469 阅读 · 0 评论 -
GStreamer 简明教程(五):Pad 相关概念介绍,Pad Capabilities/Templates
本章基于官方教程进行一些说明和补充。本来想对进行讨论的,但我的机器上安装 gtk 后运行程序总是崩溃,因此放弃。在前面的章节中也有泛泛地提到过 Pad,例如GStreamer 简明教程(二):基本概念介绍,Element 和 Pipeline和GStreamer 简明教程(三):动态调整 Pipeline。接下来这一章,我们将对 Pad 这个在 GStreamer 中非常重要的概念进行详细阐述。在 GStreamer 中,Pad 是连接不同元素之间的接口,允许它们相互通信和传递数据的概念。原创 2024-08-25 21:31:22 · 1470 阅读 · 0 评论 -
GStreamer 简明教程(四):Seek 以及获取文件时长
如何查询 Pipeline 的信息,例如时长,当前播放位置等如何进行 seek 操作。原创 2024-08-21 20:15:12 · 1255 阅读 · 0 评论 -
GStreamer 简明教程(三):动态调整 Pipeline
本章来了解 GStreamer 动态调整 Pipeline 的流程,这章代码略长,略微有些复杂,各位看官稍稍耐心些。在src参数表示触发信号的 GstElement,在本例中通常为 uridecodebin,因为它是唯一附加了该信号的元素。信号处理函数的第一个参数始终是触发信号的对象。new_pad参数表示刚刚添加到src元素的 GstPad。通常,我们希望连接的就是这个 pad。第一次,添加的 pad 负责输出视频数据第二次,添加的 pad 负责输出音频数据data。原创 2024-08-17 15:10:00 · 1414 阅读 · 0 评论 -
GStreamer 简明教程(二):基本概念介绍,Element 和 Pipeline
在上一章中我们成功的搭建了 GStreamer 的调试环境,并运行了 Hello World 程序。本章我们将介绍 GStreamer 中的基本概念,包括 Element 和 Pipeline。另外,还介绍使用 gst-inspect-1.0 程序来查看插件的基本信息。GStreamer 是基于插件的架构,它处处离不开插件,你几乎所有功能都是被封装在插件之中。因此如何查询插件信息是我们需要掌握的。原创 2024-08-13 21:34:47 · 1896 阅读 · 0 评论 -
GStreamer 简明教程(一):环境搭建,运行 Basic Tutorial 1 Hello world!
本系列文章将纪录学习 [GStreamer] 的过程。多媒体处理是一个复杂的任务,[GStreamer] 的管道架构可以将复杂的任务以「图」的形式模块化的进行处理,它足够灵活。学习 [GStreamer] 这种架构思想,可以帮助我扩展视野,面对复杂任务如何给出一套灵活可靠的框架。掌握 [GStreamer] 对求职有所帮助,如果你对 [GStreamer] 很熟悉,很多音视频岗位是可以加分的。原创 2024-08-09 22:09:56 · 2258 阅读 · 0 评论 -
LearnOpenGL - Android OpenGL ES 3.0 多线程同步,fence、glWaitSync 和 glClientWaitSync 的运用
本章讨论 OpenGL ES 中多线程技术的运用。首先,说明我们为什么需要这项技术,在 ARM OpenGL ES 教程中提到当我们转向更复杂的图形应用程序时,可能会想要使用多线程(MT)。一个典型的情况是,我们的图形应用程序需要执行大量的数学运算。在这种情况下,可能通过将工作量移至不同于管理图形操作的线程来提高性能。另一个常见的例子是我们想让图形用户界面(GUI)在一个独立的线程中运行。多线程的好处非常重要。MT使得我们的应用程序始终保持响应,并且不只是与应用程序的GUI有关。原创 2024-07-21 22:01:56 · 1745 阅读 · 0 评论 -
LearnOpenGL - Android OpenGL ES 3.0 基础特效实现
本章我们学习下如何来写一个基础特效,本文所有代码你可以在找到本文介绍了 8 中基础特效的实现逻辑,所有代码可以在找到。原创 2024-07-12 10:16:58 · 1559 阅读 · 0 评论 -
LearnOpenGL - Android OpenGL ES 3.0 使用 FBO 进行离屏渲染
利用 FBO(Framebuffer Object),我们可以实现离屏渲染。在前面的章节中,当我们调用 glDrawElements 后,手机屏幕上就会显示出绘制的图像。这意味着 OpenGL 将数据直接渲染到了手机屏幕上。通过使用 FBO,我们可以将数据渲染到纹理上,而不是直接渲染到屏幕,这个过程称为离屏渲染。通过离屏渲染,我们可以在最终显示之前对图像进行复杂的处理。这种方法非常有用,比如在后期处理效果(如模糊、HDR、阴影等)中,或者在渲染多个场景以进行纹理贴图、环境映射等操作时。原创 2024-06-27 18:30:32 · 2242 阅读 · 0 评论 -
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 · 1475 阅读 · 2 评论 -
LearnOpenGL - Android OpenGL ES 3.0 绘制纹理
在LearnOpenGL - Android OpenGL ES 3.0 绘制三角形中我们学会了如何在 Android 下搭建 GLES 环境,并绘制三角形。本文我们将讨论如何绘制纹理。本文代码在顶点着色器: 执行次数与顶点数量相同,每个顶点执行一次。片元着色器: 执行次数与片元(像素)数量相同,每个片元执行一次。因此,片元着色器的执行次数通常远多于顶点着色器的执行次数,因为片元数量通常大于顶点数量。具体执行次数取决于渲染的几何图形在屏幕上的覆盖范围。原创 2024-06-21 10:05:14 · 1094 阅读 · 0 评论 -
GStreamer 源码编译,在 Clion 下搭建调试环境
最近在学习 GStreamer,官方提供了一些,本人希望能够断点调试,以便学习代码逻辑。本文记录如何在 Clion 搭建 GStreamer 源码编译、调试环境。原创 2024-06-15 17:52:01 · 780 阅读 · 0 评论 -
Android MediaCodec 简明教程(九):使用 MediaCodec 解码到纹理,使用 OpenGL ES 进行处理,并编码为 MP4 文件
在上一章节,我们已经探讨了如何使用 OpenGL ES 处理解码后的纹理,将彩色画面转换为灰色画面,并在 GLSurfaceView 上展示。在本章节,我们将研究如何将处理后的视频帧保存为本地的 MP4 文件。本文所有代码可以在找到。原创 2024-05-31 22:09:27 · 2662 阅读 · 2 评论 -
Android MediaCodec 简明教程(八):使用 MediaCodec 解码到纹理,使用 OpenGL ES 进行处理并显示在 GLSurfaceView 上
在之前的教程中,我们已经学习了如何使用 MediaCodec 解码视频到 OES 纹理。在这篇文章中,我们将进一步探讨如何使用 OpenGL ES 将彩色图像转换为灰色图像,并在 GLSurfaceView 上显示。本文所有代码你可以在中找到。原创 2024-05-19 20:18:53 · 1522 阅读 · 0 评论 -
Android MediaCodec 简明教程(七):使用 MediaCodec 解码到 OES 纹理上
在这个系列的第七章中,我们将深入探讨一些更复杂的知识点:如何将视频帧解码到OES纹理上。在前几章中,我们已经学习了如何查询MediaCodec信息,以及如何使用MediaCodec进行解码和编码。首先,我们需要理解为什么我们需要将视频帧解码到纹理上。Android MediaCodec 简明教程(四):使用 MediaCodec 将视频解码到 Surface,并使用 SurfaceView 播放视频,我们直接将视频帧解码到SurfaceView上进行播放,这种方法并没有对视频帧进行任何处理。原创 2024-05-09 21:54:11 · 1907 阅读 · 0 评论 -
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 · 3187 阅读 · 0 评论 -
Android MediaCodec 简明教程(五):使用 MediaCodec 编码 ByteBuffer 数据,并保存为 MP4 文件
前面我们了解了 MediaCodec 解码的具体使用流程,包括异步和同步模式、解码到 ByteBuffers 或者 Surface。本章开始,我们将开始学习如何使用 MediaCodec 进行编码。与解码类似,MediaCodec 编码的输入支持 ByteBuffer 或者 Surface。遵循循序渐进的原则,我们从最简单的一种情况开始讲起:MediaCodec 编码过程中,输入的图像数据存放在 ByteBuffer 中。原创 2024-03-04 16:37:10 · 6395 阅读 · 0 评论 -
盲水印、暗水印(Blind Watermark)算法简明教程:算法原理、流程以及基于C/C++ 的代码实现
盲水印(blind watermark)算法是一种将数字水印嵌入到数字媒体中的技术,而不需要原始媒体文件。与传统的数字水印技术不同,盲水印算法不需要原始媒体文件来提取数字水印,因此更加安全和隐私保护。盲水印算法的基本原理是将数字水印嵌入到数字媒体的频域或空域中,使得数字水印能够在不影响原始媒体质量的情况下被提取出来。盲水印算法通常包括两个主要步骤:嵌入和提取。在嵌入阶段,数字水印被嵌入到数字媒体中。这通常涉及到将数字水印转换为频域或空域信号,并将其嵌入到数字媒体中。原创 2024-02-21 18:16:26 · 12100 阅读 · 3 评论 -
Android MediaCodec 简明教程(一):使用 MediaCodecList 查询 Codec 信息,并创建 MediaCodec 编解码器
最近在学习 Android MediaCodec 相关的知识,准备开个新坑把学习过程记录下来,总结成 MediaCodec 教程。在介绍 MediaCodec 编解码之前,让我们学习一些其他与之配套的组件,今天要讲的是。提示:以下是本篇文章正文内容,下面案例可供参考本文介绍了 MediaCodecList 的基本使用方法,并展示了如何使用 MediaCodecList 来创建 MediaCodec 编解码器。原创 2024-01-08 10:10:48 · 4519 阅读 · 0 评论 -
在 Android 上使用 MediaExtractor 和 MediaMuxer 提取视频\提取音频\转封装\添加音频等操作
之前我们介绍了 FFmpeg 并利用它解封装、编解码的能力完成了一款简易的视频播放器。额外的 so 文件。你需要将多个 so 文件集成至你的 app 中,使得 app 整体体积增加。额外的复杂性。这里的复杂性包括多个方面:集成的复杂性。为了引入 ffmpeg,你在编译脚本需要额外对这些库进行维护;此外,通常你不需要 FFmpeg 的全部能力,因此在编译 FFmpeg 库时你需要对其进行裁剪,这部分也需要额外的付出。编程的复杂性。原创 2024-01-02 17:34:48 · 3766 阅读 · 1 评论 -
基于 FFmpeg 的跨平台视频播放器简明教程(十二):Android SurfaceView 显示图片和播放视频
上一章中我们介绍了一个简易的播放器架构,对之前零碎的代码片段进行了组织和重构,形成了较为灵活的一种架构设计,它非常简单,但足够满足我们的需求。现在,接着我们在 Android 上的旅程。今天我们来讨论如何在 Android 上显示画面。Android 原生的 Java/Kotlin 接口播放视频还是很容易的,有 MediaController、MediaPlayer 等类可以直接使用,相关教程参考Android实现视频播放的3种实现方式。原创 2023-12-22 15:46:47 · 1044 阅读 · 0 评论 -
基于 FFmpeg 的跨平台视频播放器简明教程(十):在 Android 运行 FFmpeg
在前九章的学习中,我们已经成功地实现了一个基础的播放器,它拥有视频播放、音画同步、快进/快退等基本功能。当然,这个简易的示例还有许多可以优化的地方,比如添加更美观的用户界面,或者增加字幕功能等。然而,这并不是本教程的主要关注点。本系列文章更关注于跨平台播放器框架的构建,特别是在移动端。因此,从本章开始,我们将把重点转向 Android 端播放器的开发。前置知识包括一些 Android 的基本开发,以及 JNI 开发等。这些前置知识默认你有所了解,本文不会涉及。关于 JNI 可以参考笔者之前写的。原创 2023-10-26 21:56:45 · 1541 阅读 · 0 评论 -
基于 FFmpeg 的跨平台视频播放器简明教程(九):Seek 策略
经过前面八章的学习与代码实现,我们的播放器已经能够正常播放视频了,接下来我们将加入最常用的 seek 能力,让你能够快进/快退。本文参考文章来自。这个系列对新手较为友好,但 2015 后就不再更新了,以至于文章中的 ffmpeg api 已经被弃用了。幸运的是,有人对该教程的代码进行重写,使用了较新的 api,你可以在找到这些代码。本文的代码在和。本文介绍了播放器中如何实现快进、快退功能,并给出了具体的实现代码,还讨论了如何实现精准 seek 逻辑,并在最后给出了一些优化的思路。本文的代码在和。原创 2023-10-20 10:27:53 · 2036 阅读 · 1 评论 -
基于 FFmpeg 的跨平台视频播放器简明教程(八):音画同步
本文介绍了如何实现播放器的音画同步,首先介绍了 I/P/B 帧的区别,引出了 PTS 和 DTS 的概念;接着,介绍了在 FFmpeg 中的 timebase 的概念,让读者了解 FFmpeg 是如何描述时间的;然后,我们详细的描述了音画同步实施的具体要点,包括如何精确的纪录不同流的当前时间,在什么时间节点来更新时钟,以及音画同步的具体算法。原创 2023-08-09 21:23:08 · 2064 阅读 · 1 评论 -
基于 FFmpeg 的跨平台视频播放器简明教程(七):使用多线程解码视频和音频
在上篇文章中基于 FFmpeg 的跨平台视频播放器简明教程(六):使用 SDL 播放音频和视频,我们能够同时播放画面和音频。其中 SDL 启动了一个音频线程,每次需要音频数据时都会回调到我们定义的函数。现在,我们需要对视频显示做同样的事情。这么做能让我们的代码更加模块化,更容易使用。本文参考文章来自。这个系列对新手较为友好,但 2015 后就不再更新了,以至于文章中的 ffmpeg api 已经被弃用了。幸运的是,有人对该教程的代码进行重写,使用了较新的 api,你可以在找到这些代码。本文的代码在。原创 2023-07-28 21:29:51 · 1579 阅读 · 0 评论 -
基于 FFmpeg 的跨平台视频播放器简明教程(六):使用 SDL 播放音频和视频
在上篇文章基于 FFmpeg 的跨平台视频播放器简明教程(五):使用 SDL 播放视频中,我们使用 FFmpeg + SDL 来播放视频画面,但仅仅只是画面。今天,我们将讨论如何使用 FFmpeg + SDL 同时播放画面和声音。本文参考文章来自。这个系列对新手较为友好,但 2015 后就不再更新了,以至于文章中的 ffmpeg api 已经被弃用了。幸运的是,有人对该教程的代码进行重写,使用了较新的 api,你可以在找到这些代码。本文的代码在。原创 2023-07-10 21:21:00 · 1926 阅读 · 0 评论 -
基于 FFmpeg 的跨平台视频播放器简明教程(五):使用 SDL 播放视频
经过前面四章的学习,现在我们已经掌握了如何使用 FFmpeg 进行视频解码,中间穿插了很多音视频相关的知识点,例如容器、编解码器、解封装、像素格式、格式转换等等。现在回看,音视频的入门门槛还是比较高的,一个最简单的任务就已经涉及到大量的知识点。但问题不大,本人希望通过一系列的文章来带你入门,通过完成一个播放器项目来不断地学习音视频内容。,用于解封装相关的任务,用于解码相关的任务,用于 AVFrame 格式转换这些类的使用方式,你可以在单元测试中找到示例,此处不再赘述。资源管理。原创 2023-07-04 21:36:31 · 1924 阅读 · 0 评论 -
基于 FFmpeg 的跨平台视频播放器简明教程(三):视频解码
在前面章节基于 FFMPEG 的跨平台视频播放器简明教程(二):基础知识和解封装(demux)中我们引入了视频编解码的基础知识以及解封装的概念。请记住我们的任务:使用 ffmpeg 解码视频,并将解码后的视频帧保存在本地(就像对视频截图一样)。今天,围绕这个任务让我们继续下一个知识点:视频解码。本文参考文章来自。这个系列对新手较为友好,但 2015 后就不再更新了,以至于文章中的 ffmpeg api 已经被弃用了。幸运的是,有人对该教程的代码进行重写,使用了较新的 api,你可以在找到这些代码。原创 2023-06-10 15:35:27 · 2465 阅读 · 0 评论 -
MLT 视频编辑框架简介(三):使用与示例
在MLT 视频编辑框架简介(二):框架设计简述我们总结了 mlt 中各模块的使用方式,我们先回顾下上期的内容:Producer:Producer 是数据的来源,它负责从各种来源(如文件、网络流、生成器等)读取音视频数据。Producer 是一个基本的组件,它生成帧并将它们传递给其他组件进行处理。Filter:Filter 是对输入帧执行某种操作的组件。这些操作可以包括更改颜色、添加特效、调整音量等。原创 2023-04-25 10:18:31 · 2525 阅读 · 2 评论 -
YUV 文件读取、显示、缩放、裁剪等操作教程
本文代码你可以在项目中找到,simple_yuv_viewer 是一个基于 Dear ImGUI 和 SDL 的 YUV 文件显示工具,向你展示了如何去读取 YUV 文件,如何使用 SDL 显示它,以及如何使用 libyuv 来对 YUV 进行缩放、裁剪等操作。本文首先介绍了 Chroma subsampling 的概念,接着针对不同的 YUV 格式给出了导入 YUV 文件的正确姿势。原创 2023-01-12 19:09:05 · 3669 阅读 · 1 评论 -
【音频处理】Fast Convolution 快速卷积算法简介
这篇文章中我们介绍了卷积在信号系统中的重要意义,卷积算法复杂度为 O(N^2),为了加速卷积计算,人们提出了快速卷积算法,本文介绍了 FFT 卷积,Overlap-Add 和 Overlap-Save 块卷积,以及均匀分割卷积算法。算法的相关实现都在,包括 python 版本和 C++ 版本。......原创 2022-08-18 07:37:17 · 6877 阅读 · 0 评论 -
SDL2 简明教程(四):用 SDL_IMAGE 库导入图片
非常棒!sdl_image可以支持多种格式图片,需要用IMG_Load代替即可。你需要初始化和清理sdl_image,这些都非常简单。本文所有代码可以在找到。原创 2022-07-21 19:44:26 · 4611 阅读 · 0 评论 -
SDL2 简明教程(三):显示图片
在这篇文章中,我们研究了如何创建渲染器、表面和纹理。我们用这些来加载位图并在屏幕上显示它们。我们还看到了将图像复制到窗口的某个区域,和使其填满整个窗口之间的区别。本文源码你可以在找到。httpshttpshttpshttps。...原创 2022-07-20 21:08:00 · 2559 阅读 · 3 评论 -
SDL2 简明教程(二):创建一个空的窗口
本文介绍了如何使用SDL2创建一个空的窗口,你可以指定窗口的位置,大小等信息。为了让窗口保持存在,我们引入一个无限循环直到满足退出条件,关闭窗口触发SDL_QUIT事件,通过等待该事件,随后关闭窗口。本文源码你可以在找到。https。......原创 2022-07-19 20:29:46 · 3245 阅读 · 0 评论