当前位置: 首页 > news >正文

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

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

音视频入门基础: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。比如pts为4096,time_base为44100分之一,则pts_time等于4096乘以44100分之一 ,等于0.092880秒。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【开发工具】Maven Dependency Helper:IntelliJ IDEA的贴心助手,助力梳理依赖关系
  • Numba最近邻插值(CPU+ GPU + Z轴切块 + XYZ轴切块 + 多线程)
  • 论文解读:《LAMM: Label Alignment for Multi-Modal Prompt Learning》
  • 使用FFmpeg实现简单的拉流、推流、视频解码Demo
  • CoreDownload - WordPress文章下载增强插件v1.0.6
  • C++代码片段
  • 【Redis】redis5种数据类型(哈希)
  • 正点原子阿尔法ARM开发板-IMX6ULL(三)——汇编LED驱动实验-上
  • docker conda
  • 【Postgresql】地理空间数据的存储与查询,查询效率优化策略,数据类型与查询速度的影响
  • 国家商用密码算法——SM4、SM7、SM9
  • 一区霜冰算法+双向深度学习模型+注意力机制!RIME-BiTCN-BiGRU-Attention
  • C语言 ——— 学习并使用条件编译指令
  • 【佳学基因检测】如何使用Letsencrypt对一个网站进行加密?
  • 【Python常用库_1】网络安全清洁专家——Bleach
  • 【跃迁之路】【463天】刻意练习系列222(2018.05.14)
  • 002-读书笔记-JavaScript高级程序设计 在HTML中使用JavaScript
  • Android开源项目规范总结
  • const let
  • Docker 笔记(2):Dockerfile
  • Essential Studio for ASP.NET Web Forms 2017 v2,新增自定义树形网格工具栏
  • extjs4学习之配置
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • Octave 入门
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • pdf文件如何在线转换为jpg图片
  • React-flux杂记
  • 大整数乘法-表格法
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 基于Mobx的多页面小程序的全局共享状态管理实践
  • 如何在GitHub上创建个人博客
  • 使用SAX解析XML
  • 小程序开发中的那些坑
  • 延迟脚本的方式
  • 一个JAVA程序员成长之路分享
  • HanLP分词命名实体提取详解
  • ​1:1公有云能力整体输出,腾讯云“七剑”下云端
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • ​Spring Boot 分片上传文件
  • #QT 笔记一
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (动态规划)5. 最长回文子串 java解决
  • (二)fiber的基本认识
  • (接口封装)
  • (一) 初入MySQL 【认识和部署】
  • (一)kafka实战——kafka源码编译启动
  • (转)Linux整合apache和tomcat构建Web服务器
  • (转)从零实现3D图像引擎:(8)参数化直线与3D平面函数库
  • (自用)gtest单元测试
  • ***监测系统的构建(chkrootkit )
  • .apk 成为历史!
  • .net core webapi Startup 注入ConfigurePrimaryHttpMessageHandler
  • .NET Core 通过 Ef Core 操作 Mysql
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .NET MAUI Sqlite程序应用-数据库配置(一)