VLC缓冲机制简介

播放器的缓冲区管理一般在demxuer模块,VLC也不例外,缓冲逻辑的对外接口文件是

vlc/modules/demux/adaptive/logic/BufferingLogic.hpp

这里先看下对外(demuxer)透出的能力:

const vlc_tick_t AbstractBufferingLogic::BUFFERING_LOWEST_LIMIT = VLC_TICK_FROM_SEC(2);
const vlc_tick_t AbstractBufferingLogic::DEFAULT_MIN_BUFFERING = VLC_TICK_FROM_SEC(6);
const vlc_tick_t AbstractBufferingLogic::DEFAULT_MAX_BUFFERING = VLC_TICK_FROM_SEC(30);
const vlc_tick_t AbstractBufferingLogic::DEFAULT_LIVE_BUFFERING = VLC_TICK_FROM_SEC(15);
 
class AbstractBufferingLogic
{
    public:
        AbstractBufferingLogic();
        virtual ~AbstractBufferingLogic() {}
 
        virtual uint64_t getStartSegmentNumber(BaseRepresentation *) const = 0;
        virtual vlc_tick_t getMinBuffering(const BasePlaylist *) const = 0;
        virtual vlc_tick_t getMaxBuffering(const BasePlaylist *) const = 0;
        virtual vlc_tick_t getLiveDelay(const BasePlaylist *) const = 0;
        virtual vlc_tick_t getStableBuffering(const BasePlaylist *) const = 0;
        void setUserMinBuffering(vlc_tick_t);
        void setUserMaxBuffering(vlc_tick_t);
        void setUserLiveDelay(vlc_tick_t);
        void setLowDelay(bool);
        static const vlc_tick_t BUFFERING_LOWEST_LIMIT;
        static const vlc_tick_t DEFAULT_MIN_BUFFERING;
        static const vlc_tick_t DEFAULT_MAX_BUFFERING;
        static const vlc_tick_t DEFAULT_LIVE_BUFFERING;
 
    protected:
        vlc_tick_t userMinBuffering;
        vlc_tick_t userMaxBuffering;
        vlc_tick_t userLiveDelay;
        Undef<bool> userLowLatency;
};

从接口看提供的逻辑很简单,设置/获取最小/大的缓冲区,是否开启低延时等接口。这里简单梳理一下调用关系

本文结尾底部,领取最新最全C++音视频学习提升资料,内容包括(C/C++Linux 服务器开发,FFmpeg webRTC rtmp hls rtsp ffplay srs↓↓↓↓↓↓文章底部

  

附上关键线程代码:

void PlaylistManager::Run()
{
    mutex_locker locker {lock};
    // 这里获取前面createLogic时的配置值,这里会影响后面返回的缓冲状态
    const vlc_tick_t i_min_buffering = bufferingLogic->getMinBuffering(playlist);
    const vlc_tick_t i_max_buffering = bufferingLogic->getMaxBuffering(playlist);
    const vlc_tick_t i_target_buffering = bufferingLogic->getStableBuffering(playlist);
    while(1)
    {
        while(!b_buffering && !b_canceled)
            waitcond.wait(lock);
        if (b_canceled)
            break;
 
        if(needsUpdate())
        {
            if(updatePlaylist())
                scheduleNextUpdate();
            else
                failedupdates++;
        }
 
        vlc_mutex_lock(&demux.lock);
        vlc_tick_t i_nzpcr = demux.i_nzpcr;
        vlc_mutex_unlock(&demux.lock);
 
        // 主要是在这里,这里会返回缓冲区状态
        AbstractStream::BufferingStatus i_return = bufferize(i_nzpcr, i_min_buffering,
                                                             i_max_buffering, i_target_buffering);
 
        // 缓存只要不是特别少还是要进里面的逻辑
        if(i_return != AbstractStream::BufferingStatus::Lessthanmin)
        {
            // 说白了不同的状态只是wait的时间不同
            vlc_tick_t i_deadline = vlc_tick_now();
            if(i_return == AbstractStream::BufferingStatus::Ongoing)
                i_deadline += VLC_TICK_FROM_MS(10);
            else if(i_return == AbstractStream::BufferingStatus::Full)
                i_deadline += VLC_TICK_FROM_MS(100);
            else if(i_return == AbstractStream::BufferingStatus::End)
                i_deadline += VLC_TICK_FROM_SEC(1);
            else /*if(i_return == AbstractStream::BufferingStatus::suspended)*/
                i_deadline += VLC_TICK_FROM_MS(250);
 
            // TODO: The current function doesn't seem to modify shared
            //       state under demux lock.
            vlc_cond_signal(&demux.cond);
 
            while(b_buffering &&
                    waitcond.timedwait(lock, i_deadline) == 0 &&
                    i_deadline > vlc_tick_now() &&
                    !b_canceled);
            if (b_canceled)
                break;
        }
    }
}

这里在讲一下上面提到的缓冲状态,源码没有注释,看起来也是晦涩难懂,附到代码注释中,如果有理解不到位的地方欢迎指正:

enum class BufferingStatus {
    End = 0, /* prioritized */  // 结束的状态,类似EOF
    Suspended,   // 起播时候还在fakeEsOut或者直播超过最新的playlist的时候的状态
    Full,        // 缓冲区满了
    Ongoing,     // 介于满和Lessthanmin之间的状态,最常见的状态
    Lessthanmin, // 缓冲数据量小于最小阈值i_min_buffering
};

原文链接 

猜你喜欢

转载自blog.csdn.net/m0_60259116/article/details/125414091