leandromoreira /digital_video_introduction

A hands-on introduction to video technology: image, video, codec (av1, vp9, h265) and more (ffmpeg encoding). Translations: 🇺🇸 🇨🇳 🇯🇵 🇮🇹 🇰🇷 🇷🇺 🇧🇷 🇪🇸

★ 16,384⑂ 1,379
16,384
stars
+6+6+42
1,379
forks
–
watchers
–
prs
–
issues
–
releases
–
discussions

README

🇺🇸
🇨🇳
🇯🇵
🇮🇹
🇰🇷
🇷🇺
🇧🇷
🇪🇸



 介绍

这是一份循序渐进的视频技术的介绍。尽管它面向的是软件开发人员/工程师,但我们希望对任何人而言,这份文档都能简单易学。这个点子产生于一个视频技术新手小型研讨会期间。

本文档旨在尽可能使用浅显的词语,丰富的图像和实际例子介绍数字视频概念,使这些知识能适用于各种场合。你可以随时反馈意见或建议,以改进这篇文档。

“自己动手”需要安装 docker,并将这个 repo clone 到你的计算机。

bash
git clone https://github.com/leandromoreira/digital_video_introduction.git
cd digital_video_introduction
./setup.sh


 注意:当你看到 ./s/ffmpeg 或 ./s/mediainfo 命令时,说明我们运行的是 docker 容器中的版本,容器已经包含了程序所需的依赖。

所有的 “自己动手”应从本 repo 的根目录运行。jupyter 的示例应使用 ./s/start_jupyter.sh 启动服务器,然后复制 URL 到你的浏览器中使用。

 更新日志

 增加 DRM 系统
 发布版本 1.0.0
 添加简体中文翻译
 添加FFmpeg oscilloscope滤镜示例

 目录

- 介绍
- 目录
- 基本术语
   编码彩色图像的其它方法
   自己动手:玩转图像和颜色
   DVD 的 DAR 是 4:3
   自己动手:检查视频属性
- 消除冗余
   颜色,亮度和我们的眼睛
    + 颜色模型
    + YCbCr 和 RGB 之间的转换
    + 色度子采样
    + 自己动手:检查 YCbCr 直方图
   帧类型
    + I 帧(帧内,关键帧)
    + P 帧(预测)
      - 自己动手:具有单个 I 帧的视频
    + B 帧(双向预测)
      - 自己动手:使用 B 帧比较视频
    + 小结
   时间冗余(帧间预测)
      - 自己动手:查看运动向量
   空间冗余(帧内预测)
      - 自己动手:查看帧间预测
- 视频编解码器是如何工作的?
   是什么?为什么?怎么做?
   历史
    + AV1 的诞生
   通用编解码器
   第一步 - 图片分区
    + 自己动手:查看分区
   第二步 - 预测
   第三步 - 转换
    + 自己动手:丢弃不同的系数
   第四步 - 量化
    + 自己动手:量化
   第五步 - 熵编码
    + VLC 编码
    + 算术编码
    + 自己动手:CABAC vs CAVLC
   第六步 - 比特流格式
    + H.264 比特流
    + 自己动手:检查 H.264 比特流
   回顾
   H.265 如何实现比 H.264 更好的压缩率?
- 在线流媒体
   通用架构
   逐行下载和自适应流
   内容保护
- 如何使用 jupyter
- 会议
- 参考

 基本术语

一个图像可以视作一个二维矩阵。如果将色彩考虑进来,我们可以做出推广:将这个图像视作一个三维矩阵——多出来的维度用于储存色彩信息。

如果我们选择三原色(红、绿、蓝)代表这些色彩,这就定义了三个平面:第一个是红色平面,第二个是绿色平面,最后一个是蓝色平面。

!an image is a 3d matrix RGB

我们把这个矩阵里的每一个点称为像素(图像元素)。像素的色彩由三原色的强度(通常用数值表示)表示。例如,一个红色像素是指强度为 0 的绿色,强度为 0 的蓝色和强度最大的红色。粉色像素可以通过三种颜色的组合表示。如果规定强度的取值范围是 0 到 255,红色 255、绿色 192、蓝色 203 则表示粉色。

  编码彩色图像的其它方法

 还有许多其它模型也可以用来表示色彩,进而组成图像。例如,给每种颜色都标上序号(如下图),这样每个像素仅需一个字节就可以表示出来,而不是 RGB 模型通常所需的 3 个。在这样一个模型里我们可以用一个二维矩阵来代替三维矩阵去表示我们的色彩,这将节省存储空间,但色彩的数量将会受限。

 !NES palette


例如以下几张图片。第一张包含所有颜色平面。剩下的分别是红、绿、蓝色平面(显示为灰调)(译注:颜色强度高的地方显示为亮色,强度低为暗色)。


!RGB channels intensity

我们可以看到,对于最终的成像,红色平面对强度的贡献更多(三个平面最亮的是红色平面),蓝色平面(最后一张图片)的贡献大多只在马里奥的眼睛和他衣服的一部分。所有颜色平面对马里奥的胡子(最暗的部分)均贡献较少。

存储颜色的强度,需要占用一定大小的数据空间,这个大小被称为颜色深度。假如每个颜色(平面)的强度占用 8 bit(取值范围为 0 到 255),那么颜色深度就是 24(83)bit,我们还可以推导出我们可以使用 2 的 24 次方种不同的颜色。

 很棒的学习材料:现实世界的照片是如何拍摄成 0 和 1 的。

图片的另一个属性是分辨率,即一个平面内像素的数量。通常表示成宽高,例如下面这张 4x4 的图片。

!image resolution

  自己动手:玩转图像和颜色

 你可以使用 jupyter(python, numpy, matplotlib 等等)玩转图像。

 你也可以学习图像滤镜(边缘检测,锐化,模糊。。。)的原理。

图像或视频还有一个属性是宽高比,它简单地描述了图像或像素的宽度和高度之间的比例关系。

当人们说这个电影或照片是 16:9 时,通常是指显示宽高比(DAR),然而我们也可以有不同形状的单个像素,我们称为像素宽高比(PAR)。

!display aspect ratio

!pixel aspect ratio

  DVD 的 DAR 是 4:3

 虽然 DVD 的实际分辨率是 704x480,但它依然保持 4:3 的宽高比,因为它有一个 10:11(704x10/480x11)的 PAR。

现在我们可以将视频定义为在单位时间内连续的 n 帧,这可以视作一个新的维度,n 即为帧率,若单位时间为秒,则等同于 FPS (每秒帧数 Frames Per Second)。

!video

播放一段视频每秒所需的数据量就是它的比特率(即常说的码率)。
 比特率 = 宽  高  颜色深度  帧每秒

例如,一段每秒 30 帧,每像素 24 bits,分辨率是 480x240 的视频,如果我们不做任何压缩,它将需要 82,944,000 比特每秒或 82.944 Mbps (30x480x240x24)。

当比特率几乎恒定时称为恒定比特率(CBR);但它也可以变化,称为可变比特率(VBR)。

 这个图形显示了一个受限的 VBR,当帧为黑色时不会花费太多的数据量。

 !constrained vbr

在早期,工程师们想出了一项技术能将视频的感官帧率加倍而没有消耗额外带宽。这项技术被称为隔

Snapshot: 2026-11-10T09:35:25Z · Data license Apache-2.0 · JSON