文档章节

老调重弹之ffmpeg视频时间同步

b
 b-q
发布于 2016/10/01 22:12
字数 868
阅读 198
收藏 0

之前尝试了对视频数据的解码和简单的显示,解码完一帧图像就显示,然后立即再解码下一帧并显示,相当于一个视频以XN倍的快进播放完。现在尝试对视频图像做时间同步,即按正常的视频速率播放。

DTS和PTS

首先有两个概念:DTS和PTS。一个是解码时间,一个是显示时间。对视频的编码,并不是一个帧就包含该帧的所有数据。简单地理解就是,很多时候,前后两帧视频图像之间的差别并不大,若两个帧用用完整的图像数据进行编码,相当于浪费了空间。因此,有些帧的数据只是对前一帧的的差值,这个帧需要参考前一帧的数据才能正确地解码出图像。然后,有些格式的帧,不仅要参考前面的帧,还要参考后面的帧,这样,在这一帧解码时,需要后面的帧先解码。这样就有了解码时间和显示时间。

ffmpeg中与时间有关的结构

AVPacketAVFrameAVCodecContextAVStream中与时间相关的成员

  • AVPacket:

    int64_t pts;
    int64_t dts;
    int64_t duration;
    int64_t pos;
    

    ptsdtsduration都是以AVStream->time_base为单位。对ptsdts,如果文件是没有存储这个时间的话,其值将是AV_NOPTS_VALUE。对 duration,如果不知道的话,其值会是0pos是packet在流中的位置,以字节计数,如果不知道的话,其值为-1

  • AVFrame

    int64_t pts;
    int64_t best_effort_timestamp;
    int repeat_pict;
    int64_t pkt_pts;
    int64_t pkt_dts;
    int64_t pkt_pos;
    int64_t pkt_duration;
    int pkt_size;
    int nb_samples;
    int64_t smaple_rate;
    uint64_t channel_layout;
    int channels;
    

    best_effort_timestamp用多种方式估算出的帧的时间戳,以stream中的time base为单位。应该使用av_frame_get_best_effort_timestamp(frame)函数来获取该值。 repeat_pict: 指示这个图像必须延时多长,extra_delay = repeat_pict / (2*fps) pkt_ptspkt_dts是从相应的AVPacket中复制来。 sample_rate音频数据的采样率。 nb_samples音频数据每个通道的采样数。 channel_layout音频数据的通道布局。 channels音频数据的通道数。使用av_frame_get_channles(frame)来获取该值。

  • AVCodecContext

    AVRational time_base;
    AVRational framerate;
    

time_base:显示帧的时间戳的基本单位(秒)。若fps固定,其值就是1/framerate,且时间戳的值每次加1。解码时这个值的使用被废弃,而应使用framerate。 framerate:{0,1} when unkonwn.

  • AVStream
AVRational time_base;
int64_t start_time;
int64_t duration;
int64_t nb_frames;

time_base:显示帧的时间戳的基本单位(秒)。

视频图像显示的时间同步

简单地,有两种方法:

  • 解码时简单地延时,延时时间为帧显示的时间,再解码下一帧和显示。 在之前代码基本上,在显示完一帧图片后:
 frame_delay = av_q2d(pcodecContext->time_base);
 frame_delay += pframe->repeat_pict * (frame_delay * 0.5);
 av_usleep(frame_delay * 1000 * 1000);
  • 解码还是不断地进行,只是在显示一帧时,计算出当前帧的显示时长,包括延时,在时长过了后,再显示下一帧。 可以通过设置定时器来实现,当定时器超时时,向窗口发消息来显示下一帧。由于一个帧解码后并不立即显示,所以需要一个列表来保存解码后的帧。我们可以再顺便把读packet和解码pakcet分开来,用一个列表来保存读到的packet,解码需要packet时再从这个列表中获取。

© 著作权归作者所有

b

b-q

粉丝 0
博文 3
码字总数 3170
作品 0
闵行
私信 提问
Android使用FFmpeg(六)--ffmpeg实现音视频同步播放

关于 Android使用FFmpeg(一)--编译ffmpeg Android使用FFmpeg(二)--Android Studio配置ffmpeg Android使用FFmpeg(三)--ffmpeg实现视频播放 Android使用FFmpeg(四)--ffmpeg实现音频播放(使用A...

天王盖地虎626
01/14
0
0
Android使用FFmpeg(七)--ffmpeg实现暂停、快退快进播放

Android使用FFmpeg(一)--编译ffmpeg Android使用FFmpeg(二)--Android Studio配置ffmpeg Android使用FFmpeg(三)--ffmpeg实现视频播放 Android使用FFmpeg(四)--ffmpeg实现音频播放(使用AudioTr...

天王盖地虎626
01/14
0
0
最新FFmpeg音视频核心技术精讲与实战(完整版)

第1章 课程导学与准备工作 全民娱乐时代,需要音视频等多媒体产品层出不穷,但会处理音视频数据的工程师却极度匮乏,进入音视频开发领域正当时,这门课程就是为这样的你而生。来吧!加入我们...

L272339
01/06
0
0
2018FFmpeg音视频核心技术精讲与实战(已完结)目前最新

第1章 课程导学与准备工作 全民娱乐时代,需要音视频等多媒体产品层出不穷,但会处理音视频数据的工程师却极度匮乏,进入音视频开发领域正当时,这门课程就是为这样的你而生。来吧!加入我们...

聂友华
2018/12/18
0
0
FFmpeg音视频核心技术精讲与实战(最新分享)

第1章 课程导学与准备工作 全民娱乐时代,需要音视频等多媒体产品层出不穷,但会处理音视频数据的工程师却极度匮乏,进入音视频开发领域正当时,这门课程就是为这样的你而生。来吧!加入我们...

qq_38704763
2018/12/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

rsync工具常用选项以及同步的两种方式

rsync -av /etc/passwd /tmp/1.txt #rsync的本机传输写法 rsync -av /tmp/1.txt 192.168.188.128:/tmp/2.txt #rsync的远程传输rsync格式rsync [OPTION] … SRC ......

林怡丰
今天
3
0
GatewayWorker 报错:stream_socket_server(): unable to connect to tcp://0.0.0.0:1238

GatewayWorker 报错:stream_socket_server(): unable to connect to tcp://0.0.0.0:1238 (Address already in use) 官方文档虽然有相同的问题,但是对我的问题没起作用…… 后面发现自己手贱...

wenzhizhong
昨天
3
0
REST接口

文章来源 https://zhuanlan.zhihu.com/p/28674721?group_id=886181549958119424 http://www.ruanyifeng.com/blog/2014/05/restful_api.html REST 对请求的约定 REST 用来规范应用如何在 HTTP......

Airship
昨天
6
0
Spring Cloud Config 统一配置中心

Spring Cloud Config 统一配置中心 一、统一配置中心 统一管理配置 通常,我们会使用配置文件来管理应用的配置。如一个 Spring Boot 的应用,可以将配置信息放在 application.yml 文件中,如...

非摩尔根
昨天
6
0
android ------ AAPT2 error: check logs for details解决方法

AAPT 是全称是 Android Asset Packaging Tool,它是构建 App,甚至是构建 Android 系统都必不可少的一个工具。它的作用是将所有资源文件压缩打包到Android APK 当中。我们在 Android SDK 目录...

切切歆语
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部