ffmpeg编解码——时间基(time base)概念

文章目录

  • [FFmpeg 编解码------时间基(Time Base)概念](#FFmpeg 编解码——时间基(Time Base)概念)
    • [1. 时间基(Time Base)概念](#1. 时间基(Time Base)概念)
      • [1.1 定义与作用](#1.1 定义与作用)
      • [1.2 表现形式](#1.2 表现形式)
    • [2. 时间基在FFmpeg中的应用](#2. 时间基在FFmpeg中的应用)
      • [2.1 时间戳](#2.1 时间戳)
      • [2.2 持续时间](#2.2 持续时间)
    • [3. 理解FFmpeg中的时间基转换](#3. 理解FFmpeg中的时间基转换)
      • [3.1 `av_rescale_q` 函数](#3.1 av_rescale_q 函数)
      • [3.2 `av_rescale_q_rnd` 函数](#3.2 av_rescale_q_rnd 函数)
    • [4. 时间基相关操作的代码示例](#4. 时间基相关操作的代码示例)
    • [5. 用时间基概念分析ffprobe查看视频文件信息packet中的各字段](#5. 用时间基概念分析ffprobe查看视频文件信息packet中的各字段)
      • [1. 使用ffprobe查看视频信息](#1. 使用ffprobe查看视频信息)
      • [2. ffprobe输出的字段解析](#2. ffprobe输出的字段解析)
        • [2.1 `pts` 和 `dts`](#2.1 ptsdts)
        • [2.2 `duration`](#2.2 duration)
        • [2.3 `time_base`](#2.3 time_base)
        • [2.4 `stream_index`](#2.4 stream_index)
      • [3. 时间基在ffprobe中的应用](#3. 时间基在ffprobe中的应用)
      • [4. 理解帧和数据包](#4. 理解帧和数据包)

FFmpeg 编解码------时间基(Time Base)概念

FFmpeg是一个非常强大的开源多媒体处理工具库。在处理视频和音频流时,理解其时间基(Time Base)概念至关重要。这篇文章将分析时间基在FFmpeg中的应用,并以实例代码进行演示。

1. 时间基(Time Base)概念

1.1 定义与作用

时间基,即Time Base,是用于衡量时间的单位,在多媒体编程中被广泛使用。对于FFmpeg,它主要用于描述帧率、持续时间和时间戳等概念。简单地说,时间基是一种将数值时间戳转化为真实时间(秒)的方式。

1.2 表现形式

时间基通常表现为一个分数,比如1/25,这表示每帧的持续时间为0.04秒(即1除以25)。在FFmpeg的数据结构中,AVStream->time_base字段就用来表示时间基。

2. 时间基在FFmpeg中的应用

2.1 时间戳

在FFmpeg中,时间戳是根据特定的时间基进行计算的。时间戳可以看作是帧在媒体流中的位置或播放时间。例如,如果时间基是1/50,那么时间戳20就代表了该帧位于媒体流的0.4秒处。

2.2 持续时间

持续时间也是根据时间基来计算的。例如,一个视频片段有50帧,如果时间基是1/25,那么这个视频片段的持续时间就是2秒(即50乘以1/25)。

3. 理解FFmpeg中的时间基转换

FFmpeg为我们提供了方便的API进行时间基之间的转换,主要有av_rescale_qav_rescale_q_rnd两个函数。这两个函数可以用于在不同时间基之间转换时间戳。

3.1 av_rescale_q 函数

c 复制代码
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)

该函数的作用是将时间戳从一个时间基转换到另一个时间基。它会确保结果是最接近原值的整数。

3.2 av_rescale_q_rnd 函数

c 复制代码
int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq, enum AVRounding)

这个函数和av_rescale_q类似,但它允许用户选择四舍五入的方式。

4. 时间基相关操作的代码示例

以下是一个使用FFmpeg API处理时间基的简单示例:

c 复制代码
AVFormatContext *fmt_ctx;
AVStream *stream;
int64_t timestamp;

// 假设fmt_ctx和stream已经被正确初始化

timestamp = av_rescale_q(stream->cur_dts, stream->time_base, AV_TIME_BASE_Q);

在这个示例中,av_rescale_q函数用于将当前解码时间戳(DTS)从流的时间基转换为全局时间基。

5. 用时间基概念分析ffprobe查看视频文件信息packet中的各字段

ffprobe是一个非常实用的工具,它能够提供媒体文件(如视频和音频)的详细信息。

1. 使用ffprobe查看视频信息

要查看视频文件的信息,我们可以使用以下命令:

shell 复制代码
ffprobe -show_packets video.mp4

这条命令将显示视频文件中所有包的信息。

2. ffprobe输出的字段解析

下面是ffprobe可能输出的一些字段,以及它们的含义:

2.1 ptsdts

pts(Presentation Time Stamp)和dts(Decoding Time Stamp)表示每个数据包应该何时被展示和解码。它们的值都是相对于时间基的。

2.2 duration

duration字段表示数据包的持续时间,同样是相对于时间基的。

2.3 time_base

time_base字段就是我们前面讨论的时间基,它为上述时间戳和持续时间提供了参考。

2.4 stream_index

stream_index字段表示当前数据包属于哪个流。例如,对于多语言电影,可能有多个音频流。

3. 时间基在ffprobe中的应用

时间基在ffprobe输出中起着至关重要的作用。通过将ptsdtsduration乘以时间基,我们可以得到实际的展示、解码和持续时间。

例如,如果一个数据包的pts是18000,time_base是1/90000(这是很常见的视频时间基),那么该数据包应在0.2秒处被展示。

shell 复制代码
pts (in seconds) = pts * time_base = 18000 * 1/90000 = 0.2

4. 理解帧和数据包

在FFmpeg中,数据包(packet)和帧(frame)是两个不同的概念。一帧通常对应于一个完整的图像,而一个数据包可能包含多个帧,或者一个帧的一部分。

这意味着我们不能仅根据数据包的数量来计算视频的总时长。正确的做法是将每个数据包的duration相加,然后乘以time_base

shell 复制代码
total_duration (in seconds) = sum(duration for each packet) * time_base
相关推荐
yunhuibin5 小时前
ffmpeg面向对象——拉流协议匹配机制探索
学习·ffmpeg
cuijiecheng201812 小时前
音视频入门基础:FLV专题(13)——FFmpeg源码中,解析任意Type值的SCRIPTDATAVALUE类型的实现
ffmpeg·音视频
小神.Chen1 天前
YouTube音视频合并批处理基于 FFmpeg的
ffmpeg·音视频
昱禹3 天前
记一次因视频编码无法在浏览器播放、编码视频报错问题
linux·python·opencv·ffmpeg·音视频
寻找09之夏3 天前
【FFmpeg 深度解析】:全方位视频合成
ffmpeg·音视频
zanglengyu3 天前
ffmpeg取rtsp流音频数据保存声音为wav文件
ffmpeg·音视频
cuijiecheng20183 天前
音视频入门基础:FLV专题(11)——FFmpeg源码中,解析SCRIPTDATASTRING类型的ScriptDataValue的实现
ffmpeg·音视频
汪子熙3 天前
什么是 LDAC、SBC 和 AAC 音频编码技术
ffmpeg·音视频·aac
cpp_learners4 天前
Windows环境 源码编译 FFmpeg
windows·ffmpeg·源码编译·ffmpeg源码编译
cuijiecheng20184 天前
音视频入门基础:FLV专题(8)——FFmpeg源码中,解码Tag header的实现
ffmpeg·音视频