音视频入门核心概念:容器、编码、流与时间戳

目录

[1. 核心比喻:快递包裹](#1. 核心比喻:快递包裹)

[2. 关键知识点详解](#2. 关键知识点详解)

[2.1. 容器 (Container) vs. 编码 (Encoding)](#2.1. 容器 (Container) vs. 编码 (Encoding))

容器 (Container)

编码 (Encoding / Codec)

[2.2. 流 (Stream) 与 解复用 (Demultiplexing)](#2.2. 流 (Stream) 与 解复用 (Demultiplexing))

[2.3. 核心参数 (Stream Parameters)](#2.3. 核心参数 (Stream Parameters))

[2.4. 时间基 (Time Base / time_base)](#2.4. 时间基 (Time Base / time_base))

[2.5. PTS / DTS](#2.5. PTS / DTS)

PTS (Presentation Timestamp / G/示时间戳)

DTS (Decoding Timestamp / 解码时间戳)

[🧩 一句话总览](#🧩 一句话总览)

[📦 容器(Container)](#📦 容器(Container))

[🎞 流(Stream)](#🎞 流(Stream))

[⚙️ 编码(Codec)](#⚙️ 编码(Codec))

[⏱ 时间戳(PTS / DTS)](#⏱ 时间戳(PTS / DTS))

[✅ 总结一句话](#✅ 总结一句话)


本文档详细解释了"阶段 I:本地播放与时钟同步"中第一周"容器与解复用"所涉及的核心知识点。理解这些概念是使用 FFmpeg 进行任何音视频开发(包括播放器、转码器、分析工具)的基石。

1. 核心比喻:快递包裹

理解音视频文件,最简单的比喻就是收发快递

  • 视频/音频裸数据(H.264, AAC): 这是你购买的商品,比如一件毛衣或一部手机。它们是真正有内容的东西。

  • 编码 (Encoding): 为了方便运输,商品需要被压缩打包 。比如毛衣被抽真空,手机装在防震泡沫里。这就是 H.264 (视频编码)AAC (音频编码) 所做的事情------它们是压缩原始音视频数据的算法。

  • 容器 (Container - MP4, MKV): 这是快递盒子 。这个盒子里可以同时装下被压缩的毛衣(视频)和手机(音频),甚至还有一张说明书(字幕)。MP4 , MKV , FLV 就是这种"盒子",它们规定了如何把不同的数据"装"进去。

  • 解复用 (Demuxing): 这就是你拆快递的过程。你打开盒子(容器),把里面的毛衣(视频流)和手机(音频流)分开,准备单独使用。

2. 关键知识点详解

2.1. 容器 (Container) vs. 编码 (Encoding)

这是最容易混淆,也最重要的概念。

容器 (Container)
  • 作用: "打包"和"组织"。它是一个外壳,定义了如何将一个或多个编码后的数据流(视频、音频、字幕等)交织存储在一个单一的文件中。

  • 它包含什么:

    1. 数据流 (Streams): 至少一个视频流和一个音频流。

    2. 元数据 (Metadata): 关于文件本身的信息(如标题、作者、封面图)和关于数据流的信息(如视频分辨率、音频采样率)。

    3. 索引/时间信息: 用于播放器快速定位(Seek)到特定时间点。

  • 常见例子: .mp4, .mkv (Matroska), .mov, .flv, .ts (MPEG-TS)。

  • FFmpeg 函数: avformat_open_input 就是用来"打开容器"的函数。avformat_... 系列函数主要处理容器层面的操作(解复用)。

编码 (Encoding / Codec)
  • 作用: "压缩"。它是一种算法(即 Co der-Decoder,编解码器),用于压缩原始的、巨大的音视频数据,使其变得足够小,易于存储和网络传输。

  • 它做什么:

    • 视频编码: 利用人眼的视觉特性(如对亮度比对色度敏感,对动态画面感知模糊等)和图像帧之间的相似性来移除冗余数据。

    • 音频编码: 利用人耳的听觉特性(心理声学模型)来移除人耳听不到或不敏感的声音数据。

  • 常见例子:

    • 视频: H.264 (AVC), H.265 (HEVC), VP9, AV1。

    • 音频: AAC, MP3, Opus, FLAC (无损)。

  • FFmpeg 函数: avcodec_find_decoder 是用来"查找解码器"的。avcodec_... 系列函数主要处理编码层面的操作(解码)。

总结: 一个 .mp4 文件不是 一种视频格式。它是一个容器 ,里面可能 装着一个 H.264 编码的视频流和一个 AAC 编码的音频流。你的 MediaProbe 工具的任务之一,就是打开这个 mp4 盒子,然后告诉用户:"嘿,这个盒子里装的是 H.264 视频和 AAC 音频"。

2.2. 流 (Stream) 与 解复用 (Demultiplexing)

  • 流 (Stream): 一个连续的数据序列,代表一种特定类型的内容。在一个媒体文件中:

    • 通常有一个视频流AVMEDIA_TYPE_VIDEO)。

    • 通常有一个或多个音频流AVMEDIA_TYPE_AUDIO),例如对应不同语言(国语、英语)或不同声道(立体声、5.1声道)。

    • 可能有零个或多个字幕流AVMEDIA_TYPE_SUBTITLE)。

    • 可能有其他数据流 ,如封面图(AV_DISPOSITION_ATTACHED_PIC)。

  • 解复用 (Demuxing):

    • 当你用 avformat_open_input 打开一个文件时,FFmpeg 会读取文件的头部信息,识别出这是一个什么容器(如 MP4)。

    • 当你调用 avformat_find_stream_info 时,FFmpeg 会进一步读取文件开头的一小部分数据,分析并填充每个"流"的详细信息。

    • 这些信息被存储在一个名为 AVFormatContext 的结构体中,它里面有一个 streams 数组(AVStream**),数组的每个元素 (AVStream*) 就代表一个流。

    • 你的 MediaProbe 工具就是要遍历这个 streams 数组,提取并展示每个 AVStream 中的参数。

2.3. 核心参数 (Stream Parameters)

你的任务是列出这些参数,它们都可以在 AVStream 及其关联的 AVCodecParameters 结构中找到:

  • 编解码器 (Codec): codecpar->codec_id。例如 AV_CODEC_ID_H264

  • 分辨率 (Resolution): codecpar->widthcodecpar->height。(仅视频)

  • 帧率 (Frame Rate): avg_frame_rate。这是一个分数(AVRational),比如 30000/1001 (即 29.97 fps)。

  • 采样率 (Sample Rate): codecpar->sample_rate。例如 44100 Hz 或 48000 Hz。(仅音频)

  • 码率 (Bitrate): codecpar->bit_rate。每秒的数据量,如 5000000 (bps) = 5000 (kbps)。

  • 时长 (Duration): duration。这是一个整数,单位是 time_base

2.4. 时间基 (Time Base / time_base)

这是 FFmpeg 中最重要、也最基础的概念。

  • 是什么: 时间基(time_base)是一个分数AVRational),它定义了时间戳的单位

  • 为什么需要它: 在媒体处理中,我们从不 使用浮点数(如 2.5 秒)来记录时间,因为这会产生累积的精度误差。相反,我们使用整数"滴答数"(ticks)来记录时间戳。

  • time_base 就是 "1 滴答" 等于 "多少秒"。

  • 公式: 时间(秒) = 时间戳(整数) * time_base

  • 示例:

    • 一个流的 time_base1/90000(一种常见的值)。

    • 这个流中一个数据包的 pts(见下文)是 180000

    • 那么这个数据包对应的G/示时间就是:180000 * (1 / 90000) = 2.0 秒。

  • 注意: 不同的流(甚至容器本身)可能有不同的 time_baseAVStream 中就有自己的 time_base。在进行时间计算时,你必须使用对应流的 time_base

  • 时长计算: AVStream->duration 是一个整数,单位是 AVStream->time_base

    • 总时长(秒) = stream->duration * av_q2d(stream->time_base)

    • ( av_q2d 是 FFmpeg 提供的将 AVRational 转换为 double 的辅助函数)

2.5. PTS / DTS

PTSDTS 是存储在每个音视频数据包 (AVPacket) 上的时间戳 。它们都是整数,单位就是它们所属流的 time_base

PTS (Presentation Timestamp / G/示时间戳)
  • 含义: "这个数据包(解码后)应该在什么时候被G/示给用户"。

  • 作用: 这是播放器用于音视频同步唯一 依据。播放器会努力确保在 PTS 时间点 T,G/示第 N 帧视频,并播放第 M 块音频。

  • 对于音频流和没有 B 帧的视频流,PTS 总是单调递增的。

DTS (Decoding Timestamp / 解码时间戳)
  • 含义: "这个数据包应该在什么时候被送入解码器"。

  • 为什么需要它(B 帧的存在):

    • 现代视频编码(如 H.264)为了追求高压缩率,引入了 B 帧(双向预测帧)

    • B 帧需要参考它前面后面的帧才能解码。

    • 例子:

      • G/示顺序 (PTS): I(1), B(2) , B(3), P(4)

      • 为了解码 B(2)B(3),解码器需要先有 I(1)P(4)

      • 因此,P(4) 必须在 B(2)B(3) 之前被解码。

      • 解码顺序 (DTS) 必须是: I(1), P(4) , B(2) , B(3)

  • 总结:

    • 数据包在文件中是按 DTS 顺序存储的。

    • 解复用器 (av_read_frame) 按 DTS 顺序把包读出来。

    • 解码器按 DTS 顺序解码。

    • 解码后,播放器根据 PTS 重新排序,然后在正确的时间G/示。

  • 重要规则: 对于没有 B 帧的流(包括所有音频流),DTS == PTS

非常棒 👍

这里是一句一句、层层递进的简明总结,帮你彻底理清:


🧩 一句话总览

容器装流,流含编码数据,时间戳定义播放顺序。


📦 容器(Container)

  • 像一个打包盒(MP4、MKV、FLV...)

  • 作用:组织并存放多条媒体流(音频、视频、字幕)

  • 提供:索引、时长、时间戳、同步信息


🎞 流(Stream)

  • 是容器里的一条轨道:视频流、音频流、字幕流

  • 每个流都有自己的参数(分辨率、采样率、编码方式)

  • FFmpeg 中对应结构:AVStream


⚙️ 编码(Codec)

  • 是"流"里的压缩格式:H.264、AAC、VP9 等

  • 决定数据如何压缩与解码

  • FFmpeg 中对应结构:AVCodec / AVCodecParameters


⏱ 时间戳(PTS / DTS)

  • 用来标记每帧的时间位置

  • PTS:什么时候显示

  • DTS:什么时候解码

  • time_base 把整数时间戳换算成秒,实现音视频同步


✅ 总结一句话

容器管理多流,流使用编码,时间戳用来同步播放。

相关推荐
sukida1008 小时前
在openSUSE-Leap-15.6-DVD-x86_64-Media自制应用软件离线包——备份91个视频解码器的rpm包
数据库·redis·音视频
zymill9 小时前
hysAnalyser --- 支持UDP实时流分析和录制功能
udp·音视频·实时音视频·ts流分析·mpegts录制
DogDaoDao13 小时前
OpenCV音视频编解码器详解
人工智能·opencv·音视频·视频编解码·h264·h265·音视频编解码
羊羊小栈13 小时前
基于YOLO+多模态大模型+人脸识别+视频检索的智慧公安综合研判平台(vue+flask+AI算法)
vue.js·人工智能·yolo·flask·毕业设计·音视频·大作业
八月的雨季 最後的冰吻1 天前
FFmpeg --15-视频解码: AVIO内存输入模式分析
ffmpeg·音视频
卍郝凝卍1 天前
NVR(网络视频录像机)和视频网关的工作方式
网络·图像处理·物联网·音视频·视频解决方案
努力犯错1 天前
Google Veo 3.1 提示词生成器:让 AI 视频创作效率翻倍的免费工具
人工智能·计算机视觉·语言模型·开源·音视频
跨境海王哥1 天前
TikTok限流:为什么TikTok视频没流量、零播放
音视频
Tracy9731 天前
DNR6521x_VC1:革新音频体验的AI降噪处理器
人工智能·音视频·xmos模组固件