FFmpeg_3.2.4+SDL_2.0.5学习(2)视频同步基础

一般来说,视频同步指的是视频和音频同步,也就是说播放的声音要和当前显示的画面保持一致。想象以下,看一部电影的时候只看到人物嘴动没有声音传出;或者画面是激烈的战斗场景,而声音不是枪炮声却是人物说话的声音,这是非常差的一种体验。 在视频流和音频流中已包含了其以怎样的速度播放的相关数据,视频的帧率(Frame Rate)指示视频一秒显示的帧数(图像数);音频的采样率(Sample Rate)表示音频一秒播放的样本(Sample)的个数。可以使用以上数据通过简单的计算得到其在某一Frame(Sample)的播放时间,以这样的速度音频和视频各自播放互不影响,在理想条件下,其应该是同步的,不会出现偏差。但,理想条件是什么大家都懂得。如果用上面那种简单的计算方式,慢慢的就会出现音视频不同步的情况。要不是视频播放快了,要么是音频播放快了,很难准确的同步。这就需要一种随着时间会线性增长的量,视频和音频的播放速度都以该量为标准,播放快了就减慢播放速度;播放快了就加快播放的速度。所以呢,视频和音频的同步实际上是一个动态的过程,同步是暂时的,不同步则是常态。以选择的播放速度量为标准,快的等待慢的,慢的则加快速度,是一个你等我赶的过程。

播放速度标准量的的选择一般来说有以下三种:

  • 将视频同步到音频上,就是以音频的播放速度为基准来同步视频。视频比音频播放慢了,加快其播放速度;快了,则延迟播放。
  • 将音频同步到视频上,就是以视频的播放速度为基准来同步音频。
  • 将视频和音频同步外部的时钟上,选择一个外部时钟为基准,视频和音频的播放速度都以该时钟为标准。
			//extra_delay = repeat_pict / (2 * fps)
			//fps = 1 / time_base
			//uint64_t pts1 = pfe->pts;
			uint64_t pts2 = pfe->best_effort_timestamp;
			double extime = pfe->repeat_pict * av_q2d(pFmtCtx->streams[vindex]->time_base) * 0.5;//对齐
			double showtime = pts2 * av_q2d(pFmtCtx->streams[vindex]->time_base) + extime;

			static double time1 = timeGetTime();//0
			static double time2 = 0;
			static double preshow = 0;
			static double delay = showtime - preshow;

			time2 = timeGetTime();
			if (time1 > time2 || time1 == 0)
				time1 = time2;
			if (preshow >= showtime)
				preshow = showtime;
			if ((time2 - time1) < showtime*1000)//if(time2 - time1 < delay*1000)
				SDL_Delay(delay * 1000);

			delay = showtime - preshow;
			preshow = showtime;

			sws_scale(img_ctx, pfe->data, pfe->linesize, 0, vCodecCtx->height, YUV->data, YUV->linesize);
			SDL_UpdateTexture(texture, &rect, YUV->data[0], YUV->linesize[0]);
			SDL_RenderClear(renderer);
			SDL_RenderCopy(renderer, texture, NULL, NULL);
			SDL_RenderPresent(renderer);

			//time1 = timeGetTime();

如果把视频流看做一个数组,那么显示时间戳就像是数组下标,指示该图片帧应该显示的时间。

*pfe显示时间 = pfe->best_effort_timestamp * av_q2d(视频流的时基) + extra_delay

   extra_delay = pfe->repeat_pict / (2*fps)

   fps = 1 / av_q2d(视频流的时基)

extra_delay = pfe->repeat_pict * 0.5 * av_q2d(视频流的时基)

本例以第一帧的播放时间作为基准,适当延迟后续帧的播放时间,达到(动态)播放的效果。经测试,效果和用暴风影音的几乎一毛一样。

以后再考虑把音视频的解码播放封装成一个类,做一个真正的播放器(到时候应该以音频作为同步的基准)。

代码下载

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏杨建荣的学习笔记

时间序列数据库InfluxDB初探(r12笔记第74天)

性能监控中的很多数据都是根据时间维度来生成的,就算是很少的几台服务器,如果设置了大量的监控项,每天的数据量也是很客观的,再加上是成千上万的服务器,这个量级就...

3367
来自专栏DannyHoo的专栏

iOS开发中使用百度地图计算两点间的距离

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010105969/article/details/...

582
来自专栏数据之美

网站数据统计分析之二:前端日志采集是与非

在上一篇《网站数据统计分析之一:日志收集原理及其实现》中,咱们详细的介绍了整个日志采集的原理与流程。但是不是这样在真实的业务环境中就万事大吉了呢?事实往往并非如...

3087
来自专栏携程技术中心

干货 | 快速排障,VI能帮你做什么

1003
来自专栏腾讯社交用户体验设计

微信小程序初体验(上)

1132
来自专栏阮一峰的网络日志

防止网页被嵌入框架的代码

最近,国内开始流行另一种流氓行为:使用框架(Frame),将你的网页嵌入它的网页中。 比如,有一家网站号称自己是"口碑聚合门户",提供全国各个网上论坛的精华内容...

3054
来自专栏双十二技术哥

关于应用启动连续崩溃的解决思考

线上出现了大面积的崩溃或者各种不可用,那画面简直美的不敢想象。这也是任何商业项目做大之后都会花大力气在性能优化与高可用的原因,这个过程中也催生出了各种APM工具...

904
来自专栏顶级程序员

手把手教你爬取互联网资源

文 | 杨真 在资源匮乏,搞人工智能和大数据应用没有数据,做社交应用找不到用户,开发图片应用缺少图片,的情况下,如何冷启动? 最好的办法就是做一个爬虫,批量从...

4237
来自专栏腾讯数据中心

Tencent Datacenter:On the road

(建议在wifi环境下观看,土豪请随意) 视频内容 版权声明:本文为腾讯数据中心原创,欢迎转载,转载需保持原文(包括标题、导语、正文、图片、数据以及文尾的...

3375
来自专栏轮子工厂

推荐一款特别厉害的在线工具,程序员的百宝箱

今天发现了一款特别厉害的程序员在线工具网站,堪称程序员的百宝箱。可支持在线运行php、c、c++、go、python、java等主流语言,页面简单明了,通俗易懂...

712

扫码关注云+社区