富贵山庄

恒者行远,思者常新

音频录制流程

FFmpeg对各大平台的音频输入和输出的API进行了统一的封装,将输入API封装成AVInputFormat,将输出API封装成AVOutputFormat,并且将音频采集设备封装成一个音频文件进行处理,所以我们在采集音频数据的时候,可以将音频设备当做一个无限大的音频文件,不断的从音频文件中读取数据。

阅读全文 »

JNI

JNI是Java与C/C++连接的桥梁,是通过动态库的动态装载机制来实现的。(在前面将静态库和动态库的时候,讲过动态库的动态装载)
对于动态装载涉及到两个核心的函数:

  • dlopen(): 打开一个动态库,并创建一个引用该动态库的句柄
  • dlsym(): 根据动态库的句柄以及函数符号,返回该符号对应函数的地址,从而可以执行该函数

在Java中一般通过System类的loadLibrary函数来加载一个动态库,该函数底层就是通过调用dlopen函数来实现的。

1
System.loadLibrary(libraryName);
阅读全文 »

git-change

在C++14之前,所有的Iterator都是继承自std::iterator类,在这个类中定义了五个type

1
2
3
4
5
6
7
8
9
10
template<class Category, class T, class Distance = ptrdiff_t, 
class Pointer = T*, class Reference = T&>
struct iterator
{
typedef T value_type;
typedef Distance difference_type;
typedef Pointer pointer;
typedef Reference reference;
typedef Category iterator_category;
};
阅读全文 »

在c++17上,通过对value category修改,glvalue提供要被初始化的对象的地址,prvalue提供initializer。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream> 


class A {
public:
A() = default;


A(A &&prev) = delete;


// A(A &&prev) { std::cout << "Print1"; }
};
int main() {
A a = A();
std::cout << "aaa";
}

所以上面的代码,在c++17之前是编译不过的,A a = A() 这里调用了move构造,虽然编译器会优化掉,不会真正调用,但是move构造必须留着,不能删除。

但是在c++17后,是直接在value category层级,就保证了不会调用move构造。

什么是库

库是一种可执行代码的二进制形式,可以被操作系统载入到内存中执行,库根据链接不同分为静态库和动态库。

可执行文件生成的过程为:

c -> 预编译 -> 编译器 -> 汇编代码 -> 汇编器 -> 目标代码 -> 链接器 -> 可执行代码

  • 预编译:处理宏定义、删除注释、添加行号
  • 编译器:词法分析、语法分析、语义分析、代码优化
  • 汇编器:翻译成二进制
  • 链接器:合并符号表、符号解析、分配地址、重定位符号表
阅读全文 »

硬件解封装

Android平台针对音视频封装提供了MediaMuxer API,支持.mp4格式的封装;针对解封装提供了MediaExtractor API,支持.mp4等格式。

API架构

frameworks/base/media 文件夹中提供了所有音视频相关的Java层API,本文中讲述的解封装API都定义在该处。而具体的服务实现都在 frameworks/av 文件夹中

自7.0开始,MediaService被拆分成多个服务,每个服务都运行在各自的进程中。

阅读全文 »

本篇重点

音视频基础概念与相关术语的讲解

什么是视频

图像的组成

在说视频之前,我们来聊一下图像,图像是人对视觉感知的物质再现。图像是使用像素点阵来表示的,每个像素点都分配有特定的颜色和位置值。像素也是图像显示的基本单位,通常一幅1080x1920的图片,就是长度1920个像素点,宽度1080个像素点组成的矩阵。

颜色空间

像素点除了有位置外还需要有颜色信息,那么颜色在计算机中是如何表示呢?

在计算机中颜色空间有很多,这里我们介绍下常用的两种颜色空间,RGB颜色空间和YUV颜色空间。

阅读全文 »

图形渲染流程

​ 在Android中,所有的渲染都是将内容绘制到对应的Surface上,Surface作为BufferQueue的生产方,每当发生入队操作时,都会通知BufferQueue创建者进行消费,也就是SurfaceFlinger,由SurfaceFlinger进行合并,然后发送到显示器进行显示。

下面这张图描述了关键组件的工作流程:

工作流程

阅读全文 »
0%