VLC Buffering机制介绍

本文介绍了VLC播放器的缓冲机制,通过demux数据驱动,根据pcr和clock判断数据是否欠载,进入缓冲状态。分析过程中发现了两个问题:1. 播放速度变化时,缓存数据量判断有误可能导致倍速播放卡顿;2. 弱网环境下,由于pcr未及时更新,可能导致播放卡顿但无缓冲提示。VLC的缓冲时长可通过选项设置。
摘要由CSDN通过智能技术生成

一、简介

了解一定播放器知识的同学应该都知道,播放器内部是有缓存的(非直播场景)。缓存的作用主要是解决生产者和消费者速度的不匹配,给用户更好的使用体验。例如,在网络不稳定的情况下,可以提前缓存部分数据确保视频流畅播放;在网络差的情况下,可以及时弹出缓冲标志提示用户当前网络不好。下面简单介绍下VLC的Buffering机制。

我们在使用VLC播放视频时,能够明确的看到类似如下日志:

08-06 13:48:51.845 11495 12427 D VLC     : [894f9830/308b] libvlc input: Buffering 9%

显然这就是VLC的缓冲日志了,我们可以简单地通过这行日志定位到VLC的缓冲逻辑是在es_out.c的EsOutDecodersStopBuffering()函数中:

static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced )

{

    es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);

    es_out_id_t *p_es;

    vlc_tick_t i_stream_start;

    vlc_tick_t i_system_start;

    vlc_tick_t i_stream_duration;

    vlc_tick_t i_system_duration;

    //通过clock中stream的第一帧和最后一帧数据的pts计算i_stream_duration,即缓存的数据量

    if (input_clock_GetState( p_sys->p_pgrm->p_input_clock,

                                  &i_stream_start, &i_system_start,

                                  &i_stream_duration, &i_system_duration ))

        return;

    vlc_tick_t i_preroll_duration = 0;

    if( p_sys->i_preroll_end >= 0 )

        i_preroll_duration = __MAX( p_sys->i_preroll_end - i_stream_start, 0 );

    //这里i_buffering_duration其实主要是由i_pts_delay决定

    const vlc_tick_t i_buffering_duration = p_sys->i_pts_delay +

                                         p_sys->i_pts_jitter +

                                         p_sys->i_tracks_pts_delay +

                                         i_preroll_duration +

                                         p_sys->i_buffering_extra_stream - p_sys->i_buffering_extra_initial;

    //如果缓存的数据不够就直接返回;如果参数b_forced置为true,强制结束缓存

    if( i_stream_duration <= i_buffering_duration && !b_forced )

    {

        double f_level;

        if (i_buffering_duration == 0)

            f_level = 0;

        else

            f_level = __MAX( (double)i_stream_duration / i_buffering_duration, 0 );

        input_SendEventCache( p_sys->p_input, f_level );

        int i_level = (int)(100 * f_level);

        if( p_sys->i_prev_stream_level != i_level )

        {

            msg_Dbg( p_sys->p_input, "Buffering %d%%", i

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值