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
相关推荐
胖_大海_16 小时前
【FFmpeg+Surface 底层渲染,实现超低延迟100ms】
ffmpeg
冷冷的菜哥16 小时前
springboot调用ffmpeg实现对视频的截图,截取与水印
java·spring boot·ffmpeg·音视频·水印·截图·截取
进击的CJR1 天前
redis哨兵实现主从自动切换
mysql·ffmpeg·dba
huahualaly1 天前
重建oracle测试库步骤
数据库·oracle·ffmpeg
aqi002 天前
FFmpeg开发笔记(九十九)基于Kotlin的国产开源播放器DKVideoPlayer
android·ffmpeg·kotlin·音视频·直播·流媒体
lizongyao2 天前
FFMPEG命令行典型案例
ffmpeg
冷冷的菜哥2 天前
ASP.NET Core调用ffmpeg对视频进行截图,截取,增加水印
开发语言·后端·ffmpeg·asp.net·音视频·asp.net core
冷冷的菜哥2 天前
go(golang)调用ffmpeg对视频进行截图、截取、增加水印
后端·golang·ffmpeg·go·音视频·水印截取截图
小尧嵌入式3 天前
【基础学习七十】ffmpeg命令
c++·stm32·嵌入式硬件·ffmpeg
烧饼Fighting3 天前
统信UOS操作系统离线安装ffmpeg
开发语言·javascript·ffmpeg