FFMPEG处理音频时间戳的主要逻辑
来源:http://www.xuebuyuan.com/1466771.html
FFMPEG处理音频时间戳的主要逻辑
FFMPEG处理音频时间戳的主要逻辑是:
1. demux读取AVPacket。以输入flv为例,timebase是1/1000,第一个音频包可能是46,代表0.046秒。
2. decoder解码AVPacket为AVFrame,frame的pts为NOPTS,需要设置,否则后面都会有问题。主要是调用:av_rescale_delta:
AVRational in_tb = decoded_frame_tb;
AVRational fs_tb = (AVRational){1, ist->codec->sample_rate};
int duration = decoded_frame->nb_samples;
AVRational out_tb = (AVRational){1, ist->codec->sample_rate}; decoded_frame->pts = av_rescale_delta(in_tb, decoded_frame->pts, fs_tb, duration, &rescale_last_pts, out_tb);
相当于下面的逻辑:
// init the rescale_last_pts, set to 0 for the first decoded_frame->pts is 0
if (rescale_last_pts == AV_NOPTS_VALUE) {
rescale_last_pts = av_rescale_q(decoded_frame->pts, in_tb, fs_tb) + duration;
}
// the fs_tb equals to out_tb, so decoded_frame->pts equals to rescale_last_pts
decoded_frame->pts = av_rescale_q(rescale_last_pts, fs_tb, out_tb);;
rescale_last_pts += duration;
还可以简化为:
/**
* for audio encoding, we simplify the rescale algorithm to following.
*/
if (rescale_last_pts == AV_NOPTS_VALUE) {
rescale_last_pts = 0;
}
decoded_frame->pts = rescale_last_pts;
rescale_last_pts += decoded_frame->nb_samples; // duration
实际上就是以nb_samples为时长,让pts为这个的总和,累积的samples就可以。因为默认把tb设置为sample_rate,所以samples数目就是pts。
3. filter过滤,实际上没有处理。
// correct the pts
int64_t filtered_frame_pts = AV_NOPTS_VALUE;
if (picref->pts != AV_NOPTS_VALUE) {
// rescale the tb, actual the ofilter tb equals to ost tb,
// so this step canbe ignored and we always set start_time to 0.
filtered_frame_pts = av_rescale_q(picref->pts, ofilter->inputs[0]->time_base, ost->codec->time_base)
- av_rescale_q(start_time, AV_TIME_BASE_Q, ost->codec->time_base);
} // convert to frame
avfilter_copy_buf_props(filtered_frame, picref);
printf("filter -> picref_pts=%"PRId64", frame_pts=%"PRId64", filtered_pts=%"PRId64"\n",
picref->pts, filtered_frame->pts, filtered_frame_pts);
filtered_frame->pts = filtered_frame_pts;
4. encoder编码,主要是生成dts。
5. muxer输出前,需要做处理。譬如输出rtmp流,要将tb变为1/1000,flv的tb,也就是毫秒单位。
另外,时间戳从零开始。
// correct the output, enforce start at 0.
static int64_t starttime = -1;
#if 1
if (starttime < 0) {
starttime = (pkt.dts < pkt.pts)? pkt.dts : pkt.pts;
}
pkt.dts -= starttime;
pkt.pts -= starttime;
#endif #if 1
// rescale audio ts to AVRational(1, 1000) for flv format.
AVRational flv_tb = (AVRational){1, 1000};
pkt.dts = av_rescale_q(pkt.dts, ost->codec->time_base, flv_tb);
pkt.pts = av_rescale_q(pkt.pts, ost->codec->time_base, flv_tb);
#endif
6. 最后一步,写入:
ret = av_interleaved_write_frame(oc, &pkt);
就OK了。
FFMPEG处理音频时间戳的主要逻辑的更多相关文章
- [总结]FFMPEG视音频编解码零基础学习方法--转
ffmpeg编解码学习 目录(?)[-] ffmpeg程序的使用ffmpegexeffplayexeffprobeexe 1 ffmpegexe 2 ffplayexe 3 ffprobeexe ...
- FFMPEG视音频编解码零基础学习方法
在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者.在和大家探讨的过程中,我忽然发现了一个问题:在“ ...
- 最简单的基于FFMPEG的音频编码器(PCM编码为AAC)
http://blog.csdn.net/leixiaohua1020/article/details/25430449 本文介绍一个最简单的基于FFMPEG的音频编码器.该编码器实现了PCM音频采样 ...
- FFMPEG视音频编解码零基础学习方法-b
感谢大神分享,虽然现在还看不懂,留着大家一起看啦 PS:有不少人不清楚“FFmpeg”应该怎么读.它读作“ef ef em peg” 0. 背景知识 本章主要介绍一下FFMPEG都用在了哪里(在这里仅 ...
- [总结]FFMPEG视音频编解码零基础学习方法
在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者.在和大家探讨的过程中,我忽然发现了一个问题:在“ ...
- [Audio processing] FFMPEG转音频格式和采样率
利用FFMPEG转音频格式和采样率 import os import string import subprocess as sp #Full path of ffmpeg FFMPEG_BIN = ...
- 【转】[总结]FFMPEG视音频编解码零基础学习方法
在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者.在和大家探讨的过程中,我忽然发现了一个问题:在“ ...
- 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——解码篇:(二)用ffmpeg解码音频
其实这篇的内容和(一)用ffmpeg解码视频基本是一样的,重点还是给ffmpeg指定callback函数,而这个函数是从RTSP服务端那里获取音频数据的. 这里,解码音频的示例代码量之所以比解码视频的 ...
- C# 使用 ffmpeg 进行音频转码
先放一下 ffmpeg 的官方文档以及下载地址: 官方文档:http://ffmpeg.org/ffmpeg.html 下载地址:http://ffmpeg.org/download.html 用 f ...
随机推荐
- 小学四则运算口算练习app---No.4
今天主要是改了出题页中各个组件的位置以及时间的接收还有时间控制,代码如下:(但是存在一个问题 设置页面点击确定按钮进入出题界面时有时会闪退,未解决!) CalculatorActivity.clas ...
- 每天一道Rust-LeetCode(2019-06-01)
每天一道Rust-LeetCode(2019-06-01) 坚持每天一道题,刷题学习Rust. 题目描述 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的, ...
- Random Access Iterator 徐州网络赛(树形dp)
Random Access Iterator \[ Time Limit: 4000 ms \quad Memory Limit: 262144 kB \] 题意 给出伪代码,问按着伪代码在树上跑,能 ...
- SDOI2010选做
Round1 D1T1外星千足虫 \(BSOJ2793\)--高斯消元解异或方程组 简述 有\(n\)个数\(\{a_i\}\) 给出\(m\)个信息,每个信息给出\(\displaystyle{(\ ...
- 洛谷 P2023 [AHOI2009]维护序列 题解
P2023 [AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列中 ...
- Ajax运用与分页
目录 django与ajax的分页处理 ajax + sweetAlert 实现再次确认: 批量数据插入 分页: django与ajax的分页处理 ajax + sweetAlert 实现再次确认: ...
- [Gamma]Scrum Meeting#10
github 本次会议项目由PM召开,时间为6月5日晚上10点30分 时长15分钟 任务表格 人员 昨日工作 下一步工作 木鬼 撰写博客,组织例会 撰写博客,组织例会 swoip 前端显示屏幕,翻译坐 ...
- 接口性能指标TP90
TP90,即,Top percentile 90, 前90%的意思. 这是一个常用于网站性能监控的指标.tp90是一个时间值,例如tp90=3ms,其含义是90%的请求,在3ms之内,可以得到响应. ...
- CentOS安装Hadoop
Hadoop的核心由3个部分组成: HDFS: Hadoop Distributed File System,分布式文件系统,hdfs还可以再细分为NameNode.SecondaryNameNode ...
- ASP.NET-------gridview 进行编辑的时候,给出提示
在使用gridview 控件的时候,控制修改人的操作行为,并给出合理的提示, 比如 在执行编辑操作的时候 不允许姓名为空,并显示出提示,姓名不可以为空 操作: 前台页面,对一些字段的解释 一定要注意 ...