android端音视频同步
音视频流是相互独立的。其中音频解码后得到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端音视频同步相关推荐
- 如何做好 Android 端音视频测试?
在用户眼中,优秀的音视频产品应该具有清晰.低延时.流畅.秒开.抗丢包.高音效等特征.为了满足用户以上要求,网易云信的工程师通过自建源站,在SDK端为了适应网络优化进行QoS优化,对视频编码器进行优化, ...
- 基于FFmpeg和Android的音视频同步播放实现
https://blog.csdn.net/ericbar/article/details/80785764 https://blog.csdn.net/AndroidAlvin/article/de ...
- Android移动端音视频的快速开发教程(五)
接 Android移动端音视频的快速开发教程(四) 3.3. 数据传输事件接口 3.3.1. 接口定义 package com.bairuitech.anychat; // 数据传输通知接口 pub ...
- Android 短视频 SDK 转场特效的音视频同步分析
在短视频的应用场景中,经常存在用户拍摄的两个或者多个视频生成一个视频的需求,为了达到两个视频平滑过渡,就需要在两个视频中间添加转场效果. 由于导入视频的帧率.码率等参数都不一致,如何保证在添加完转场效 ...
- 深入理解Android音视频同步机制(二)ExoPlayer的avsync逻辑
深入理解Android音视频同步机制(一)概述 深入理解Android音视频同步机制(二)ExoPlayer的avsync逻辑 深入理解Android音视频同步机制(三)NuPlayer的avsync ...
- 即构互动白板音视频同步、多端协作技术实践
8月27日晚,即构联合技术社区LiveVideoStack在线上举办了互动白板的技术分享直播活动,吸引了大量在线教育及音视频相关的开发者参与.即构科技互动白板研发负责人陈晓聪在活动上分享了我们在互动白 ...
- android 音视频同步_如何轻松地将音乐,视频和照片与Android同步
android 音视频同步 Apple users have iTunes to synchronize their media libraries back and forth, but what ...
- 【Android音视频开发】【020】音视频同步原理
音视频不同步现象 由于视频解码和显示,非常消耗性能,所以视频帧无法和音频帧一样,保证每一帧都能严格准时播放 在现有技术和硬件条件下,任何库都无法百分百保证音视频同步,只能尽力保证误差最小 同步方案 一 ...
- (强烈推荐)移动端音视频从零到上手(转载)
移动端音视频从零到上手 原文链接 概述 随着整个互联网的崛起,数据传递的形式也在不断升级变化,总的流行趋势如下: 纯文本的短信,QQ -> 空间,微博,朋友圈的图片文字结合 -> 微信语音 ...
最新文章
- java的System.gc()的理解
- 通过单步调试理解Angular里routerLink指令实际url的生成逻辑
- linux组成,Linux学习笔记之Linux组成及初识
- java partialfunction,scala中方法和函数的区别
- HTML 标签的 enctype 属性
- java度分秒转换度
- android短信拦截木马,有个木马专门伪装成支付宝 它会窃取支付宝账号密码 通讯录通话记录...
- 计算机中安装音乐软件是一种,电脑必装的八款软件,你装了吗?
- 【技法操作】UI界面设计,用PS绘制录音页面教程
- ArcGIS 裁剪地图显示范围
- 项目管理之JIRA安装部署
- 改变自己是神,改变别人是神经病
- 用Photoshop制作2寸照片方法
- QQ群名片尾巴生成原理
- postman传数组
- 页面自动更新(javascript)
- QT QLabel控件(使用详解)
- 渝粤题库 陕西师范大学 电子商务安全作业
- SwiftUI实战教程之创建Tinder样式的可左右滑动卡视图(项目含源码)
- 谷歌浏览器检查打开慢,F12键(打开控制台)打开较慢?解决方法
热门文章
- 慎用一键修改hosts软件
- Shell之sed命令
- 一篇文章读懂什么是CAP(基础入门)
- 07 Linux操作系统相关知识
- 小白也能看懂:最全无线渗透测试与攻防+Fluxison钓鱼教程+路由器安全设置指南 2021.3.31
- 通用技术设计评价雷达图高考必看知识点
- 在Mysql数据库里通过存储过程实现树形的遍历
- linux sh语法进入目录,Linux_常用的Linux shell命令详解收集整理,1 文件与目录操作命令 
1.1文 - phpStudy...
- 律师:“信用卡代还业务”今年或有牢狱之灾
- 7-31 【0413】考拉兹猜想