音视频流是相互独立的。其中音频解码后得到pcm裸流,通过扬声器播放;视频解码后得到yuv再转换为rgb像素格式,通过屏幕(SurfaceView)渲染显示。与音视频同步有关的概念:dts(decode timestamp 解码时间戳)和pts(presentation timestamp 显示时间戳)。理论上音视频流的时间是呈线性的,为什么需要dts和pts呢?因为视频帧存在:I帧(关键帧 根据该帧可以重现完整画面)、P帧(非关键帧 依赖上一个I帧)和B帧(非关键帧 依赖上一个与下一个I帧)。例如某个B帧解码顺序为:1 3 2,而播放顺序为1 2 3(其中1、3为I帧,2为B帧),这就需要引入dts和pts的概念了。

音视频同步的参考时钟有三种:音频时钟、视频时钟和系统时钟。以参考时钟为基准,如果pts时间小于当前时间,丢弃该帧数据;如果pts时间大于当前时间,则休眠等待。另外休眠过程中,加上mutex互斥锁。

/*** 音视频同步方法* 如果pts时间大于当前时间,则休眠等待* 如果pts时间小于当前时间,丢弃该帧数据*/
void player_wait_for_frame(MediaPlayer *player, int64_t stream_time) {//互斥锁加锁pthread_mutex_lock(&player->mutex);for(;;){int64_t current_video_time = get_play_time(player);int64_t sleep_time = stream_time - current_video_time;if (sleep_time < -300000ll) {//pts时间落后,不用等待int64_t new_value = player->start_time - sleep_time;player->start_time = new_value;pthread_cond_broadcast(&player->cond);}if (sleep_time <= MIN_SLEEP_TIME_US) {//休眠时长小于最小阈值,不用处理break;}if (sleep_time > 500000ll) {//最大休眠时长sleep_time = 500000ll;}//等待指定时长,超时则退出等待pthread_cond_timeout_np(&player->cond, &player->mutex,(unsigned int) (sleep_time / 1000ll));}//互斥锁解锁pthread_mutex_unlock(&player->mutex);
}

获取当前播放时间:

//获取当前播放时间
int64_t get_play_time(MediaPlayer* player){return (int64_t)(av_gettime() - player->start_time);
}

视频播放时调用音视频同步方法:

//获取最佳的播放时间戳作为pts
int64_t pts = av_frame_get_best_effort_timestamp(player->yuv_frame);
//获取视频的AVStream
AVStream *stream = player->format_context->streams[player->video_stream_index];
//时间转换(不同时间基时间转换)
int64_t time = av_rescale_q(pts, stream->time_base, AV_TIME_BASE_Q);
//音视频帧同步
player_wait_for_frame(player, time);

音频播放时调用音视频同步方法:

//获取pts
int64_t pts = packet->pts;
if (pts != AV_NOPTS_VALUE) {//获取音频的AVStreamAVStream *stream = player->format_context->streams[player->audio_stream_index];//pts时间转换后作为音频时钟player->audio_clock = av_rescale_q(pts, stream->time_base, AV_TIME_BASE_Q);//音视频帧同步player_wait_for_frame(player, player->audio_clock + AUDIO_TIME_ADJUST_US);
}

好了,音视频同步介绍完毕。如果各位有什么问题或建议,欢迎交流。
源码地址: https://github.com/xufuji456/FFmpegAndroid

android端音视频同步相关推荐

  1. 如何做好 Android 端音视频测试?

    在用户眼中,优秀的音视频产品应该具有清晰.低延时.流畅.秒开.抗丢包.高音效等特征.为了满足用户以上要求,网易云信的工程师通过自建源站,在SDK端为了适应网络优化进行QoS优化,对视频编码器进行优化, ...

  2. 基于FFmpeg和Android的音视频同步播放实现

    https://blog.csdn.net/ericbar/article/details/80785764 https://blog.csdn.net/AndroidAlvin/article/de ...

  3. Android移动端音视频的快速开发教程(五)

    接  Android移动端音视频的快速开发教程(四) 3.3. 数据传输事件接口 3.3.1. 接口定义 package com.bairuitech.anychat; // 数据传输通知接口 pub ...

  4. Android 短视频 SDK 转场特效的音视频同步分析

    在短视频的应用场景中,经常存在用户拍摄的两个或者多个视频生成一个视频的需求,为了达到两个视频平滑过渡,就需要在两个视频中间添加转场效果. 由于导入视频的帧率.码率等参数都不一致,如何保证在添加完转场效 ...

  5. 深入理解Android音视频同步机制(二)ExoPlayer的avsync逻辑

    深入理解Android音视频同步机制(一)概述 深入理解Android音视频同步机制(二)ExoPlayer的avsync逻辑 深入理解Android音视频同步机制(三)NuPlayer的avsync ...

  6. 即构互动白板音视频同步、多端协作技术实践

    8月27日晚,即构联合技术社区LiveVideoStack在线上举办了互动白板的技术分享直播活动,吸引了大量在线教育及音视频相关的开发者参与.即构科技互动白板研发负责人陈晓聪在活动上分享了我们在互动白 ...

  7. android 音视频同步_如何轻松地将音乐,视频和照片与Android同步

    android 音视频同步 Apple users have iTunes to synchronize their media libraries back and forth, but what ...

  8. 【Android音视频开发】【020】音视频同步原理

    音视频不同步现象 由于视频解码和显示,非常消耗性能,所以视频帧无法和音频帧一样,保证每一帧都能严格准时播放 在现有技术和硬件条件下,任何库都无法百分百保证音视频同步,只能尽力保证误差最小 同步方案 一 ...

  9. (强烈推荐)移动端音视频从零到上手(转载)

    移动端音视频从零到上手 原文链接 概述 随着整个互联网的崛起,数据传递的形式也在不断升级变化,总的流行趋势如下: 纯文本的短信,QQ -> 空间,微博,朋友圈的图片文字结合 -> 微信语音 ...

最新文章

  1. java的System.gc()的理解
  2. 通过单步调试理解Angular里routerLink指令实际url的生成逻辑
  3. linux组成,Linux学习笔记之Linux组成及初识
  4. java partialfunction,scala中方法和函数的区别
  5. HTML 标签的 enctype 属性
  6. java度分秒转换度
  7. android短信拦截木马,有个木马专门伪装成支付宝 它会窃取支付宝账号密码 通讯录通话记录...
  8. 计算机中安装音乐软件是一种,电脑必装的八款软件,你装了吗?
  9. 【技法操作】UI界面设计,用PS绘制录音页面教程
  10. ArcGIS 裁剪地图显示范围
  11. 项目管理之JIRA安装部署
  12. 改变自己是神,改变别人是神经病
  13. 用Photoshop制作2寸照片方法
  14. QQ群名片尾巴生成原理
  15. postman传数组
  16. 页面自动更新(javascript)
  17. QT QLabel控件(使用详解)
  18. 渝粤题库 陕西师范大学 电子商务安全作业
  19. SwiftUI实战教程之创建Tinder样式的可左右滑动卡视图(项目含源码)
  20. 谷歌浏览器检查打开慢,F12键(打开控制台)打开较慢?解决方法

热门文章

  1. 慎用一键修改hosts软件
  2. Shell之sed命令
  3. 一篇文章读懂什么是CAP(基础入门)
  4. 07 Linux操作系统相关知识
  5. 小白也能看懂:最全无线渗透测试与攻防+Fluxison钓鱼教程+路由器安全设置指南 2021.3.31
  6. 通用技术设计评价雷达图高考必看知识点
  7. 在Mysql数据库里通过存储过程实现树形的遍历
  8. linux sh语法进入目录,Linux_常用的Linux shell命令详解收集整理,1 文件与目录操作命令 1.1文 - phpStudy...
  9. 律师:“信用卡代还业务”今年或有牢狱之灾
  10. 7-31 【0413】考拉兹猜想