ijkplayer 音视频同步流程分析

本文详细介绍了ijkplayer的音视频同步流程,包括音频和视频的独立播放、同步机制、结构体介绍、关键方法以及调用流程。ijkplayer通过音频时间进行同步,确保声画时间节点一致。同步过程中涉及Frame_Queue、Packet_Queue和Clock结构体的初始化,以及read_thread、音频和视频解码线程的运行。在音视频同步中,通过video_refresh_thread计算剩余同步时间并渲染视频,实现播放的流畅和同步。
摘要由CSDN通过智能技术生成

音视频同步介绍
音频和视频是各自线程独立播放的,需要同步行为来保证声画的时间节点是一致的或者时间偏差值在一定的范围内。一般来说是根据音频时间来做同步,也就是将视频同步到音频。从ijkplayer中的代码可以看出来,默认是音频除非音频通道不存在才会是视频。引起音视频不同步的原因主要有两种:一种是音频和视频的数据量不一致而且编码算法不同所引起的解码时间差导致的不同步。并且发送端没有统一的同步时钟;另一种是网络传输延时,网络传输是受到网络的实时传输带宽、传输距离和网络节点的处理速度等因素的影响,在网络阻塞时,媒体信息不能保证以连续的“流”数据方式传输,特别是不能保证数据量大的视频信息的连续传输,从而引起媒体流内和流间的失步。
ijkplayer中的结构体介绍
IjkMediaPlayer

ijkplayer 的结构体,提供播放控制和播放的状态的一些处理,结构体指针再初始化后会保存在java层,提供复用。基本每个jni的方法都会获取java 层对应对象的一个long 型变量,然后强转成此结构体。

FFPlayer

主要与java层交互的结构体,音视频的输出,软硬解码器的设置。

VideoState

FFPlay中的结构体。ijkplayer 直接拿过来包含在FFPlayer中。

Frame_Queue

保存解码后数据的环形数组,不同通道的大小不一致。

Packet_Queue

保存从文件或者流读取出来的解码前数据的队列。

Clock

一个用于音视频同步的结构体

方法介绍
stream_open

对一些结构体进行初始化,然后创建文件读取线程和视频渲染线程

ffplay_video_thread

视频解码线程执行的方法

audio_thread

音频解码线程执行的方法

video_refresh_thread

视频渲染,音视频同步

调用流程

Alt

在 stream_open 方法中,会对 Frame_Queue、Packet_Queue 和 Clock 进行初始化,如下所示。

if (frame_queue_init(&is->pictq, &is->videoq, ffp->pictq_size, 1) < 0)
goto fail;
if (frame_queue_init(&is->subpq, &is->subtitleq, SUBPICTURE_QUEUE_SIZE, 0) < 0)
goto fail;
if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
goto fail;

if (packet_queue_init(&is->videoq) < 0 ||
packet_queue_init(&is->audioq) < 0 ||
packet_queue_init(&is->subtitleq) < 0)
goto fail;

init_clock(&is->vidclk, &is->videoq.serial);
init_clock(&is->audclk, &is->audioq.serial);
init_clock(&is->extclk, &is->extclk.serial);
同时, stream_open 方法中会启动一个 read_thread 线程。在线程中会根据读取的文件或者流的信息去判断是否存在音频流和视频流,然后通过 stream_component_open 方法找到对应的解码器,启动解码线程。

if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
stream_component_open(ffp, st_index[AVMEDIA_TYPE_AUDIO]);
} else {
// 如果音频流不存在,那就没办法通过音频去同步,所以把同步方式改为视频
ffp->av_sync_type = AV_SYNC_VIDEO_MASTER;
is->av_sync_type = ffp->av_sync_type;
}
if (st_index[AVMEDIA_

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值