音视频入门基础:WAV专题(11)——FFmpeg源码中计算WAV音频文件每个packet的pts_time、dts_time的实现

news/2024/9/18 10:02:58/ 标签: 音视频, ffmpeg

=================================================================

音视频入门基础:WAV专题系列文章:

音视频入门基础:WAV专题(1)——使用FFmpeg命令生成WAV音频文件

音视频入门基础:WAV专题(2)——WAV格式简介

音视频入门基础:WAV专题(3)——FFmpeg源码中,判断某文件是否为WAV音频文件的实现

音视频入门基础:WAV专题(4)——FFmpeg源码中获取WAV文件音频压缩编码格式、采样频率、声道数量、采样位数、码率的实现

音视频入门基础:WAV专题(5)——FFmpeg源码中解码WAV Header的实现

音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息

音视频入门基础:WAV专题(7)——FFmpeg源码中计算WAV音频文件每个packet的size值的实现

音视频入门基础:WAV专题(8)——FFmpeg源码中计算WAV音频文件AVStream的time_base的实现

音视频入门基础:WAV专题(9)——FFmpeg源码中计算WAV音频文件每个packet的duration和duration_time的实现

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

音视频入门基础:WAV专题(11)——FFmpeg源码中计算WAV音频文件每个packet的pts_time、dts_time的实现

=================================================================

一、引言

从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts_time、dts_time:

打印出来的“pts_time”是以秒为单位的显示时间戳;“dts_time”是以秒为单位的解码时间戳。这两个值都是通过fftools/ffprobe.c中的show_packet函数打印出来的:

static void show_packet(WriterContext *w, InputFile *ifile, AVPacket *pkt, int packet_idx)
{
//...print_time("pts_time",        pkt->pts, &st->time_base);
//...print_time("dts_time",        pkt->dts, &st->time_base);
//...
}

本文讲述上述pts_time、dts_time的值是怎样被计算出来的。如果想直接看结论,可以跳到本文的最后,直接看“总结”。

二、FFmpeg源码中计算WAV音频文件每个packet的pts_time、dts_time的实现

从《音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现》中可以知道,pts是以AVStream->time_base为单位的显示时间戳;dts是以AVStream->time_base为单位的解码时间戳。

show_packet函数是通过print_time宏定义将pts和dts转换为pts_time和dts_time,并打印出来的:

​static void show_packet(WriterContext *w, InputFile *ifile, AVPacket *pkt, int packet_idx)
{
//...print_time("pts_time",        pkt->pts, &st->time_base);
//...print_time("dts_time",        pkt->dts, &st->time_base);
//...
}​

print_time宏定义如下,可以看到其实质是调用writer_print_time函数:

#define print_time(k, v, tb)    writer_print_time(w, k, v, tb, 0)

而writer_print_time函数的定义为:

static void writer_print_time(WriterContext *wctx, const char *key,int64_t ts, const AVRational *time_base, int is_duration)
{char buf[128];if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0)) {writer_print_string(wctx, key, "N/A", PRINT_STRING_OPT);} else {double d = ts * av_q2d(*time_base);struct unit_value uv;uv.val.d = d;uv.unit = unit_second_str;value_string(buf, sizeof(buf), uv);writer_print_string(wctx, key, buf, 0);}
}

表达式writer_print_time(w, k, v, tb, 0)中,“v”为pts或dts,“tb”为AVStream的time_base。

关于av_q2d函数的用法可以参考:《FFmpeg有理数相关的源码:AVRational结构体和其相关的函数分析》。pts_time和dts_time是由writer_print_time函数中的下面语句计算出来的:

double d = ts * av_q2d(*time_base);

简单点来讲:

pts_time = pts × time_base,

dts_time = dts × time_base。

三、总结

“pts_time”是以秒为单位的显示时间戳;“dts_time”是以秒为单位的解码时间戳。

pts_time = pts × time_base,dts_time = dts × time_base。这里的time_base指AVStream的time_base。比如pts为4096,time_base为44100分之一,则pts_time等于4096乘以44100分之一 ,等于0.092880秒。


http://www.ppmy.cn/news/1524842.html

相关文章

DMDPC单副本集群安装

1. 环境描述 2. 部署步骤 2.1. 安装DM数据库软件启动DMAP [dmdbalei1 ~]$ DmAPService status DmAPService (pid 1269) is running.2.2. 初始化数据库实例 [dmdbalei1 data]$ dminit path/dmdba/data/sp1 instance_nameSP1 port_num5236 ap_port_num6000 dpc_modeSP initdb …

如何确定kafka与zookeeper版本的对应关系

一、kafka与zookeeper版本对应关系 网上可以查到的基本都是这个样子(清一色kafka2.4.0版本一下的)!! Kafka版本 Zookeeper版本 kafka_2.12-2.7.2 zookeeper-3.5.9.jar … … kafka_2.12-2.4.0 zookeeper-3.5.6.jar kafka_2.12-2.3.1 zookeeper-3.4.14.jar …

Java JUC(一) 线程概念与常用方法

Java JUC(一) 线程概念与常用方法 一. JUC 基本概念 Java JUC(Java Util Concurrent) 是Java平台提供的一个并发编程工具包(java.util.concurrent),全称为Java Concurrency Utilities。这个工具…

网络运维故障处理案例

在当今依赖互联网的时代,网络的稳定运行对企业业务的持续性至关重要。然而,即便是最完善的网络系统也会不时出现故障。今天,我们将通过一个具体的案例,结合实际操作,来探讨网络运维中常见的故障处理方法和经验。更多内…

ChatGPT+Simple Mind Map生成思维导图:快速提升学习效率

一、告别杂乱笔记,一键生成清晰思维导图! 最近开始学习网络安全,一头扎进了各种协议、漏洞、防御机制的海洋中。信息量巨大,知识点零散,让我很快便陷入了“知识焦虑”——笔记越记越多,却越来越混乱&#…

Java 入门指南:JVM(Java虚拟机)—— Java 类文件结构

文章目录 字节码JVM 与字节码字节码的生成过程 Class 文件结构魔数(Magic Number)Class 文件版本号(Minor&Major Version)常量池(Constant Pool)访问标志(Access Flags)前类(This Class&…

数据处理与统计分析篇-day02-Linux进阶

day02-Linux进阶 补充昨日内容 Linux基础 文件编辑 命令模式 编辑模式 esc回到命令模式 正常编辑 底行(底线)模式 查看Linux命令帮助文档 # --help 可以查看命令的详细信息 命令名 --help ​ # 例如: ls --help ​ # man 可以查看命令的主要(简单)信息 man 命令名…

3个WebSocket的.Net开源项目

推荐3个有关Websocket的.Net开源项目。 一、FreeIM 一个使用Websocket协议实现的、高性能即时聊天组件,可用于群聊、好友聊天、游戏直播等场景。 1、跨平台:基于.NetCore开发,支持Windows、Mono、Liunx、Windows Azure、Docker。 2、支持…

Uni-app 开发鸿蒙 App 全攻略

一、开发前的准备工作 开发鸿蒙 App 之前,我们需要做好充分的准备工作。首先是工具的安装与配置。 Node.js 的安装:推荐使用 LTS 版本的 Node.js。可以前往 Node.js 的官方网站下载适合自己操作系统的安装包,如 Windows 用户根据自己的系统版…

DL/T645-2007 通信库(C#版本)

DL/T645-2007 通信库(C#版本) 文章目录 DL/T645-2007 通信库(C#版本)DL/T645-2007 介绍主要内容介绍:应用场景:标准的意义: DL/T645-2007 通信库(C#版本)接口展示测试用例…

jest需要mock自定义hook导出的数据,同一个测试文件不同的用例需要不同的数据,该怎么mock

当在同一个测试文件中针对不同的测试用例需要mock自定义Hook导出不同的数据时,你可以使用Jest的动态mock功能或者利用Jest的beforeEach、beforeAll等钩子函数来设置不同的mock行为。 这里是一个使用Jest的beforeEach钩子函数来为每个测试用例设置不同mock数据的示例…

JavaWeb使用web.xml配置Servlet路径映射的相关操作以及易错问题分析与解决

前言 我们在使用Servlet创建JavaWeb项目时,想要绑定url路径和Servlet的映射关系,需要在web.xml中配置映射关系。Servlet从2.5版本开始支持注解。具体来说,Servlet 2.5引入了注解配置方式,使得Servlet应用程序的配置更加简单、灵活…

PHP一键约课高效健身智能健身管理系统小程序源码

一键约课,高效健身 —— 智能健身管理系统让健康触手可及 🏋️‍♀️ 告别繁琐,一键开启健身之旅 你还在为每次去健身房前的繁琐预约流程而烦恼吗?现在有了“一键约课高效健身智能健身管理系统”,所有问题都迎刃而解…

C# 通过拖控件移动窗体

目录 引言一、通过控件事件移动窗体1、创建窗体界面2、添加控件事件3、添加代码 二、通过windowsAPI移动窗体1、 构建窗体和添加事件2、代码展示 三、其它方式 引言 在C#Form窗体设计中,如果我们不需要使用默认边框设计自己个性化的窗体(FromBorderStyl…

代码随想录 第九章 动态规划part03 01背包问题 一维 416. 分割等和子集

01背包问题 一维 #include <bits/stdc.h> using namespace std; int main(){int n, bagWeight;cin >> n >> bagWeight;std::vector<int> value(n, 0);std::vector<int> weight(n, 0);for (int i 0; i < n; i) cin >> weight[i];for (…

mysql性能优化-云服务与数据库即服务(DBaaS)优化

一、云服务与DBaaS概述 1.1 云服务的特性 云服务&#xff08;Cloud Service&#xff09;通过虚拟化技术提供了灵活的计算资源&#xff0c;按需分配且弹性伸缩。相比传统的自建数据中心&#xff0c;云服务具备以下优势&#xff1a; 弹性伸缩&#xff1a;根据业务需求&#xf…

Python发邮箱:如何配置SMTP服务器发邮件?

Python发邮箱基础教程&#xff1f;python如何实现发送邮件功能&#xff1f; 无论是工作中的项目协作&#xff0c;还是生活中的日常交流&#xff0c;电子邮件都能快速传递信息。而使用Python发邮箱&#xff0c;更是让这一过程自动化、高效化。AokSend将详细介绍如何配置SMTP服务…

使用Python和Proxy302代理IP高效采集Bing图片

目录 项目背景一、项目准备环境配置 二、爬虫设计与实现爬虫设计思路目标网站分析数据获取流程 代码实现1. 初始化爬虫类&#xff08;BingImageSpider&#xff09;2. 创建存储文件夹3. 获取图像链接4. 下载图片5. 使用Proxy302代理IP6. 主运行函数 运行截图 三、总结 项目背景 …

上海泗博EtherNet/IP转PROFIBUS DP网关EPS-320IP成都地铁项目应用案例

背景&#xff1a; 地铁&#xff0c;作为城市的活力脉搏&#xff0c;不仅是衔接城市生活的关键纽带&#xff0c;更是现代城市交通体系中不可或缺的核心组成部分。因此&#xff0c;确保地铁的稳定运行对任何一座城市都至关重要。 上海泗博自动化&#xff0c;作为与成都地铁项目合…

Linux从入门到开发实战(C/C++)Day11-aio

什么是aio&#xff1a;异步io&#xff0c;让io过程异步进行&#xff0c;从而提升读写效率 涉及状态切换&#xff1a;用户态、内核态 如何进行aio读操作&#xff1a; 执行异步操作的时候&#xff0c;函数直接返回&#xff08;可以先去做其他事情&#xff09; 同…