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 条评论
登录 后参与评论

相关文章

来自专栏web前端教室

前端新人如何快速打好基础

现在谈到WEB前端的技术结构、知识体系,都会搞出一个非常大、枝叶非常多且细的相当宏大的思维导图,

1192
来自专栏机器学习算法与Python学习

别人Python都玩腻了,而你却连安装工具库都搞不清楚!

9:00 你打开电脑,双击各部门交上来的周报,轻车熟路地开始了crtlC,ctrlV工作,把表格统计在一起。 15:00 你发现投资部的表格里多了一个字段,导致...

3839
来自专栏MixLab科技+设计实验室

全栈设计+编程的方法论,以“猜对联”小程序为例

趁着快过年,花了 2 天晚上从设计到开发,做了一款小程序 “ 猜对联 ” ,可以用于公众号吸粉,也可以朋友间拜年,也可以作为聚会的真心话大冒险游戏,玩法多样,全...

2979
来自专栏Java学习网

如何用开源经历为你的简历增加光彩

在这篇文章中,我将会分享我的方法,让大家利用开源贡献在技术领域的求职中脱颖而出,成为强有力的候选者。 凡事预则立,不预则废。在你即将进入一个新的领域或者正准备熬...

2854
来自专栏程序员宝库

2018年程序员技能调查:JavaScript企业需求最大......

近日,HackerRank 发布了2018年开发人员技能报告,其中包括开发者几岁开始学习编程,如何学习编程,最喜欢的语言和框架有哪些,他们想要什么样的工作,以及...

3728
来自专栏AI科技大本营的专栏

这次拿下Python全靠它了!一个交互式的学习资源!

你的假期余额已不足!在假期的最后一天,我们给大家介绍一本非常 nice 的 Python 学习书——Project Python。

1083
来自专栏养码场

你和硅谷顶级程序员差这5点!

程序员和程序员之间也会有区别,就好像学生之间也会有学渣、学霸之别,编程之间也各有优异。

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

从零开始的异视觉设计

1527
来自专栏小巫技术博客

关于《代码大全2》那点事

612
来自专栏即时通讯技术

近期大热的实时直播答题系统的实现思路与技术难点分享

HQ Trivia 号称直播答题的鼻祖,它是一款小知识互动游戏,由短视频社交鼻祖Vine的联合创始人拉斯-尤苏波夫和科林-克罗尔共同开发

1232

扫码关注云+社区