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

ffmpeg 问答系列-> mux 部分


author: hjjdebug
date: 2025年 08月 24日 星期日 09:47:08 CST
descrip: ffmpeg 问答系列-> mux 部分


文章目录

  • 1. frame->pts 和 packet->pts 是什么关系?
  • 2 问pts 和 dts, 哪一个时间戳是严格递增的?
  • 3. av_interleaved_write_frame 的工作原理

mux 部分对frame 的pts, packet的pts, dts 要求十分严格,
这里对时间戳概念pts,dts进行一下辨析.
pts 是演播时间戳. dts 是解码时间戳. 时间戳的基准单位根据上下文可以自己设置.
frame中有时间戳pts,
packet中不仅有pts, 还有dts.

mpeg 音频frame 被编码为packet,

1. frame->pts 和 packet->pts 是什么关系?

一般是直接copy 的关系, 但也有可能差一个偏移.
对mpegaudio 而言, 其关系为:
参考代码: libavcodec/mpegaudioenc_template.c:773
if (frame->pts != AV_NOPTS_VALUE)
avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->initial_padding)

其中avctx->initial_padding 是481, 所以pkt->pts 总是比frame->pts 小481
当frame->pts=0时, pkt->pts=-481

mpeg 视频frame 被编码为packet, packet有pts 和 dts,

2 问pts 和 dts, 哪一个时间戳是严格递增的?

首先frame->pts 是严格递增的,它就是frame的个数.
然后看一下实测结果. mpeg2 编码视频.
从实验中看出, pkt->dts 是严格递增的.

vframe->pts:0    第一个frame, 被缓存,编不出pkt
--
vframe->pts:12个frame, 被缓存,编不出pkt
--
vframe->pts:22个frame, 得pkt->pts=0, pkt->dts=-1
只所以有dts, 解码时间戳,或者说为什么引入dts概念, 就是要你按解码时间戳来解码, 它是严格递增的.
pts 由于有b帧的存在, 呈现小幅波动, 例如测试的编码例子为0,3,1,2,6,4,5,9... 像喝醉酒一样往上长!pkt before rescale, pts:0,dts:-1
--
vframe->pts:3
pkt before rescale, pts:3,dts:0
--
vframe->pts:4
pkt before rescale, pts:1,dts:1
--
vframe->pts:5
pkt before rescale, pts:2,dts:2
--
vframe->pts:6
pkt before rescale, pts:6,dts:3
--
vframe->pts:7
pkt before rescale, pts:4,dts:4
--
vframe->pts:8
pkt before rescale, pts:5,dts:5
--
vframe->pts:9
pkt before rescale, pts:9,dts:6
--
vframe->pts:10
pkt before rescale, pts:7,dts:7
--
vframe->pts:11
pkt before rescale, pts:8,dts:8
--
vframe->pts:12
pkt before rescale, pts:12,dts:9

3. av_interleaved_write_frame 的工作原理

ret = av_interleaved_write_frame(fmt_ctx, pkt);

  1. 检查并修正输入AVPacket的pts/dts
  2. 设置有pkt 的链表缓冲, 通过ff_interleave_packet_per_dts默认算法按解码时间戳(DTS)排序.
  3. 先缓存数据包,当时间戳满足连续性条件时批量写入. 例如音视频包都存在且满足连续性条件.开始写入.
  4. 由AVFormatContext->max_interleave_delta参数控制最大缓冲时长. 超过该容忍度强制写入.
    里边内容还是挺多的, 可以调试源码获得第一手资料.
http://www.xdnf.cn/news/18653.html

相关文章:

  • C6.1:发射极偏置放大器
  • 阿里 通义千问 Java23种设计模式
  • IDM 下载失败排查指南:全面解析与解决方案
  • 深入解析 std::enable_if:原理、用法与现代 C++ 实践
  • 编程与数学 02-017 Python 面向对象编程 20课题、迭代器模式
  • 大数据毕业设计选题推荐-基于大数据的丙型肝炎患者数据可视化分析系统-Hadoop-Spark-数据可视化-BigData
  • 深入解析十大经典排序算法原理与实现
  • 室联人形机器人:家政服务任务结构化、技术要点、深入应用FPGA的控制系统框架设计(整合版A)
  • 【运维进阶】高可用和负载均衡技术
  • Django的Serializers与 fastapi 的Pydantic
  • 【R语言】R语言中 rbind() 与 merge() 的区别详解
  • 网络编程-创建TCP协议服务器
  • 疏老师-python训练营-Day54Inception网络及其思考
  • 屏幕类型与信号接口
  • 【KO】前端面试一
  • LLaMA-Factory 中配置文件或命令行里各个参数的含义
  • 如何利用 DeepSeek 提升工作效率
  • 10.Shell脚本修炼手册---脚本的条件测试与比较
  • 国家自然科学基金(国自然基金)申请技巧详解
  • 深度学习入门:神经网络
  • 【2025CVPR-目标检测方向】UniMamba:基于激光雷达的3D目标检测,采用分组高效曼巴语进行统一空间信道表示学习
  • Q/DR/CX7.2-2020 是中国企业标准体系中
  • 一个备份、去除、新增k8s的node标签脚本
  • `strdup` 字符串复制函数
  • 【JVM内存结构系列】二、线程私有区域详解:程序计数器、虚拟机栈、本地方法栈——搞懂栈溢出与线程隔离
  • 奇怪的前端面试题
  • 智能系统与未来生态演进初步思考
  • LangChain4j中集成Redis向量数据库实现Rag
  • 2-4.Python 编码基础 - 流程控制(判断语句、循环语句、break 语句与 continue 语句)
  • 【Python】新手入门:Python标准库有哪些常用模块?