当前位置: 首页 > news >正文

音视频开发入门小知识

什么是视频

视频就是由一系列图片构成的,当画面快速切换时,人眼看起来就感觉是连贯的动作。

视频帧

帧,表示一张画面,就是一帧。一个视频就是由许许多多帧组成的。

帧率

帧率,表示单位时间内帧的数量,单位为:帧/秒或fps,一秒内包含的帧越多,画面越顺滑,过度越自然。
帧率的一般以下几个典型值:
(1) 24/25 fps:一般的电影帧率
(2) 30/60 fps:游戏的帧率,30帧可以接受,60帧会感觉更加流畅逼真
(3) 85 fps以上人眼基本无法察觉出来了,所以更高的帧率在视频里没有太大意义

色彩空间

RGB:这个是我们最熟悉的一种,在现在的电子设备中应用广泛。通过R G B三种基础色,可以混合出所有的颜色。
YUV:这是一种亮度与色度分离的色彩格式。早期的电视都是黑白的,即只有亮度值,即Y。有了彩色电视以后,加入了UV两种色度,形成现在的YUV。
Y:亮度,就是灰度值。除了表示亮度信号外,还含有较多的绿色通道量。
U:蓝色通道与亮度的差值。
V:红色通道与亮度的差值。

YUV的优势:人眼对亮度敏感,对色度不敏感,因此减少部分UV的数据量,人眼却无法感知出来,这样可以通过压缩UV的分辨率,在不影响观感的前提下,减小视频的体积。

什么是音频

音频数据的承载方式最常用的是脉冲编码调制,即PCM。声音是一种模拟信号,想要把声音保存下来,那就是把声音数字化,即转换为数字信号。

模拟信号 --> 采样 --> 量化 --> 编码 --> 数字信号

采样率,采样位数和编码

采样率:即采样的频率,采样率要大于原声波频率的两倍,人耳能听到的最高频率为20kHz,所以为了满足人耳的听觉要求,采样率至少为40kHz,通常为44.1kHz。

采样位数:波形振幅在模拟信号上也是连续的样本值,而在数字信号中,信号一般是不连续的,所以模拟信号量化以后,只能取一个近似的整数值,为了记录这些振幅值,采样器会采用一个固定的位数来记录这些振幅值,通常有8位、16位、32位,位数越多,记录的值越准确,还原度越高。

编码:由于数字信号是由0和1组成的,因此,需要将幅度值转换为一系列0和1进行存储,也就是编码,最后得到的数据就是数字信号,一串0和1组成的数据。

声道数

声道数,是指支持能不同发声的音响的个数。
单声道:1个声道
双声道:2个声道
立体声道:默认为2个声道
立体声道(4声道):4个声道

码率

码率,是指一个数据流中每秒钟能通过的信息量,单位bps,码率 = 采样率 * 采样位数 * 声道数

为什么要编码

由于音视频的数据量庞大,如果按照裸流数据存储的话,那将需要耗费非常大的存储空间,也不利于传送。而音视频中,其实包含了大量0和1的重复数据,因此可以通过一定的算法来压缩这些0和1的数据,编码可以大大减小音视频数据的大小,让音视频更容易存储和传送。

视频编码

现在主流的编码格式是H264,H264会根据一段时间内,画面的变化情况,选取一帧画面作为完整编码,下一帧只记录与上一帧完整数据的差别,是一个动态压缩的过程。H264采用的是YUV。

音频编码

原始的PCM音频数据也是非常大的数据量,因此也需要对其进行压缩编码,音频也有许多的编码格式,如:WAV、MP3。AAC是新一代的音频有损压缩技术,一种高压缩比的音频压缩算法。在MP4视频中的音频数据,大多数时候都是采用AAC压缩格式。

音视频容器

像MP4,AVI等,其实是包裹了音视频编码数据的容器,用来把以特定编码标准编码的视频流和音频流混在一起,成为一个文件。
mp4是目前最流行的视频格式,在移动端,一般将视频封装为mp4格式。mp4支持H264视频编码和AAC或MP3等音频编码。

软解码和硬解码的区别

软解码:利用CPU的计算能力来解码,通常如果CPU的能力不是很强的时候,解码速度会比较慢,手机可能出现发热现象,但是,由于使用统一的算法,兼容性会很好。
硬解码:利用手机上专门的解码芯片来加速解码。通常硬解码的解码速度会快很多,但是由于硬解码由各个厂家实现,质量参差不齐,非常容易出现兼容性问题。谷歌官方提供了MediaCodec,供上层应用调用。

MediaCodec

MediaCodec 是Android 4.1版本引入的编解码API,支持音视频的编码和解码。采用了基于环形缓冲区的 生产者-消费者模型,异步处理数据。在 input 端,Client 是这个环形缓冲区生产者,MediaCodec 是 消费者。在 output 端,MediaCodec 是这个环形缓冲区生产者,而 Client 则变成了消费者。

工作流程

在这里插入图片描述

  1. Client 从 input 缓冲区队列申请 empty buffer [dequeueInputBuffer]
  2. Client 把需要编解码的数据拷贝到 empty buffer,然后放入 input 缓冲区队列 [queueInputBuffer]
  3. MediaCodec 从 input 缓冲区队列取一帧数据进行编解码处理
  4. 处理结束后,MediaCodec 将原始数据 buffer 置为 empty 后放回 input 缓冲区队列,将编解码后的数据放入到 output 缓冲区队列
  5. Client 从 output 缓冲区队列申请编解码后的 buffer [dequeueOutputBuffer]
  6. Client 对编解码后的 buffer 进行渲染或播放
  7. 渲染或播放完成后,Client 再将该 buffer 放回 output 缓冲区队列 [releaseOutputBuffer]

相关文章:

  • Debezium日常分享系列之:Debezium2.7版本PostgreSQL数据库连接器
  • 如何用Java实现运营商三要素接口调用
  • MySQL 进阶(三)【SQL 优化】
  • 为什么品牌需要做 IP 形象?
  • 【常见开源库的二次开发】基于openssl的加密与解密——单向散列函数(四)
  • 07. Hibernate 会话工厂(SessionFactory)
  • [数据集][目标检测]狗种类检测数据集VOC+YOLO格式20578张120类别
  • 【C++】命名空间深度理解
  • 51单片机-(定时/计数器)
  • 微服务Day6
  • 一键生成请求方法的工具 —— OpenAPI Typescript Codegen
  • C# OpenCvSharp DNN Low Light image Enhancement
  • 数据挖掘-理解业务和数据(二)
  • 温振变送器为何被称为监测工频类设备故障的“利器”?
  • 【面试题】数组去重的五种方法(必会)
  • MySQL索引
  • JavaScript基础总结---重点
  • UnRaid设备共用其他UnRaid主UPS的详细设置方法
  • ESP32的MQTT AT固件烧录+STM32以ESP32的MQTT AT固件的AT指令连接EMQX下mqtt服务器实现消息订阅和发布
  • Python 多进程编程(一)Pool Manager in multiprocessing
  • 灰度变换 - 灰度切割(灰度级分层)+threshold函数
  • MyBatis 框架的思想及其第一次使用
  • 【Unity Shader】Unity中如何创建Cubemap?
  • 面试百问:项目上线后才发现bug怎么办?
  • C语言《文件版本通讯录》
  • 【无人机】基于EKF、UKF、PF、改进PF滤波算法的无人机航迹预测(Matlab代码实现)
  • 一篇文章让你搞懂Java中的静态代理和动态代理
  • ROS1云课-导航实践测评
  • React中路由的参数传递 - 路由的配置文件
  • (附源码)计算机毕业设计SSM基于web的健康饮食信息管理系统
  • 算法的意义、如何学习算法和算法的复杂度
  • 由浅到深带你详谈Java实现数组扩容的三种方式【建议收藏】