来源:http://www.xuebuyuan.com/1466771.html

FFMPEG处理音频时间戳的主要逻辑

2013年12月09日 ⁄ 综合 ⁄ 共 2226字 ⁄ 字号 ⁄ 评论关闭
 

FFMPEG处理音频时间戳的主要逻辑是:

1. demux读取AVPacket。以输入flv为例,timebase是1/1000,第一个音频包可能是46,代表0.046秒。

2. decoder解码AVPacket为AVFrame,frame的pts为NOPTS,需要设置,否则后面都会有问题。主要是调用:av_rescale_delta:

  1. AVRational in_tb = decoded_frame_tb;
  2. AVRational fs_tb = (AVRational){1, ist->codec->sample_rate};
  3. int duration = decoded_frame->nb_samples;
  4. AVRational out_tb = (AVRational){1, ist->codec->sample_rate};
  5.  
  6. decoded_frame->pts = av_rescale_delta(in_tb, decoded_frame->pts, fs_tb, duration, &rescale_last_pts, out_tb);

相当于下面的逻辑:

  1. // init the rescale_last_pts, set to 0 for the first decoded_frame->pts is 0
  2. if (rescale_last_pts == AV_NOPTS_VALUE) {
  3. rescale_last_pts = av_rescale_q(decoded_frame->pts, in_tb, fs_tb) + duration;
  4. }
  5. // the fs_tb equals to out_tb, so decoded_frame->pts equals to rescale_last_pts
  6. decoded_frame->pts = av_rescale_q(rescale_last_pts, fs_tb, out_tb);;
  7. rescale_last_pts += duration;

还可以简化为:

  1. /**
  2. * for audio encoding, we simplify the rescale algorithm to following.
  3. */
  4. if (rescale_last_pts == AV_NOPTS_VALUE) {
  5. rescale_last_pts = 0;
  6. }
  7. decoded_frame->pts = rescale_last_pts;
  8. rescale_last_pts += decoded_frame->nb_samples; // duration

实际上就是以nb_samples为时长,让pts为这个的总和,累积的samples就可以。因为默认把tb设置为sample_rate,所以samples数目就是pts。

3. filter过滤,实际上没有处理。

  1. // correct the pts
  2. int64_t filtered_frame_pts = AV_NOPTS_VALUE;
  3. if (picref->pts != AV_NOPTS_VALUE) {
  4. // rescale the tb, actual the ofilter tb equals to ost tb,
  5. // so this step canbe ignored and we always set start_time to 0.
  6. filtered_frame_pts = av_rescale_q(picref->pts, ofilter->inputs[0]->time_base, ost->codec->time_base)
  7. - av_rescale_q(start_time, AV_TIME_BASE_Q, ost->codec->time_base);
  8. }
  9.  
  10. // convert to frame
  11. avfilter_copy_buf_props(filtered_frame, picref);
  12. printf("filter -> picref_pts=%"PRId64", frame_pts=%"PRId64", filtered_pts=%"PRId64"\n",
  13. picref->pts, filtered_frame->pts, filtered_frame_pts);
  14. filtered_frame->pts = filtered_frame_pts;

4. encoder编码,主要是生成dts。

5. muxer输出前,需要做处理。譬如输出rtmp流,要将tb变为1/1000,flv的tb,也就是毫秒单位。

另外,时间戳从零开始。

  1. // correct the output, enforce start at 0.
  2. static int64_t starttime = -1;
  3. #if 1
  4. if (starttime < 0) {
  5. starttime = (pkt.dts < pkt.pts)? pkt.dts : pkt.pts;
  6. }
  7. pkt.dts -= starttime;
  8. pkt.pts -= starttime;
  9. #endif
  10.  
  11. #if 1
  12. // rescale audio ts to AVRational(1, 1000) for flv format.
  13. AVRational flv_tb = (AVRational){1, 1000};
  14. pkt.dts = av_rescale_q(pkt.dts, ost->codec->time_base, flv_tb);
  15. pkt.pts = av_rescale_q(pkt.pts, ost->codec->time_base, flv_tb);
  16. #endif

6. 最后一步,写入:

  1. ret = av_interleaved_write_frame(oc, &pkt);

就OK了。

FFMPEG处理音频时间戳的主要逻辑的更多相关文章

  1. [总结]FFMPEG视音频编解码零基础学习方法--转

    ffmpeg编解码学习   目录(?)[-] ffmpeg程序的使用ffmpegexeffplayexeffprobeexe 1 ffmpegexe 2 ffplayexe 3 ffprobeexe ...

  2. FFMPEG视音频编解码零基础学习方法

    在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者.在和大家探讨的过程中,我忽然发现了一个问题:在“ ...

  3. 最简单的基于FFMPEG的音频编码器(PCM编码为AAC)

    http://blog.csdn.net/leixiaohua1020/article/details/25430449 本文介绍一个最简单的基于FFMPEG的音频编码器.该编码器实现了PCM音频采样 ...

  4. FFMPEG视音频编解码零基础学习方法-b

    感谢大神分享,虽然现在还看不懂,留着大家一起看啦 PS:有不少人不清楚“FFmpeg”应该怎么读.它读作“ef ef em peg” 0. 背景知识 本章主要介绍一下FFMPEG都用在了哪里(在这里仅 ...

  5. [总结]FFMPEG视音频编解码零基础学习方法

    在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者.在和大家探讨的过程中,我忽然发现了一个问题:在“ ...

  6. [Audio processing] FFMPEG转音频格式和采样率

    利用FFMPEG转音频格式和采样率 import os import string import subprocess as sp #Full path of ffmpeg FFMPEG_BIN = ...

  7. 【转】[总结]FFMPEG视音频编解码零基础学习方法

    在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者.在和大家探讨的过程中,我忽然发现了一个问题:在“ ...

  8. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——解码篇:(二)用ffmpeg解码音频

    其实这篇的内容和(一)用ffmpeg解码视频基本是一样的,重点还是给ffmpeg指定callback函数,而这个函数是从RTSP服务端那里获取音频数据的. 这里,解码音频的示例代码量之所以比解码视频的 ...

  9. C# 使用 ffmpeg 进行音频转码

    先放一下 ffmpeg 的官方文档以及下载地址: 官方文档:http://ffmpeg.org/ffmpeg.html 下载地址:http://ffmpeg.org/download.html 用 f ...

随机推荐

  1. 6.使用Go向Consul注册的基本方法

    编写注册函数 package utils import ( consulapi "github.com/hashicorp/consul/api" "log" ...

  2. 【luoguP2252】 取石子游戏

    题目链接 定义\(f[i][j]\)表示\(a=i,b=j\)时是必胜态还是必败态,博弈DP可以解决\(a,b \leq 100\) 的情况 然后就可以找规律了,发现\(f[i][j]=0\)的情况很 ...

  3. Redis内存回收策略

    如果使用Redis的时候,不合理使用内存,把什么东西都放在内存里面,又不设置过期时间,就会导致内存的堆积越来越大.根据28法则,除了20%的热点数据之外,剩余的80%的非热点或不怎么重要的数据都在占用 ...

  4. Linux配置DNS

    vi /etc/resolv.conf, 后面加上nameserver 114.114.114.114

  5. 浅谈设计模式-visitor访问者模式

    先看一个和visitor无关的案例.假设你现在有一个书架,这个书架有两种操作,1添加书籍2阅读每一本书籍的简介. //书架public class Bookcase { List<Book> ...

  6. Alpha冲刺(9/10)——2019.5.1

    作业描述 课程 软件工程1916|W(福州大学) 团队名称 修!咻咻! 作业要求 项目Alpha冲刺(团队) 团队目标 切实可行的计算机协会维修预约平台 开发工具 Eclipse 团队信息 队员学号 ...

  7. 本周使用angular7所遇到的一些问题

    前言 本周在使用angular7所遇到的一些问题,学习是不断的循序渐进的过程,在本周完成对应的工作后,也要抽出一些时间用来学习,比较我们公司10点上班,我一般9点就会到,在这一个小时内看看博客,写写笔 ...

  8. SSM 整合配置

    目录 1. Maven : pox.xml 2. Web container : web.xml 3. Spring context : dbconfig.properties + applicati ...

  9. CentOS7使用tar.gz包安装MySql的踩坑之旅

    由于客户的CentOS服务器没有安装yum工具,只能通过下载tar.gz包安装mysql,于是跟着万能的百度开启了漫漫踩坑之旅: 1.下载mysql-5.6.33-linux-glibc2.5-x86 ...

  10. 最新修改Oracle10gscott用户

    1.以system登录及输入自己设置口令; 2.更换sysdba身份: conn system/orcl as sysdba; 3.解锁scott用户(因装好默认是锁定的): alter user s ...