ijkplayer-丢帧策略深入分析

本文深入探讨了ijkplayer播放器在处理丢帧问题上的策略,对比了与系统播放器的差异。通过分析,发现在高通660设备上播放4k视频时,由于解码慢导致的频繁丢帧造成画面卡顿。ijkplayer的丢帧设计包括硬解码和软解码两种情况,主要丢弃解码后的视频帧以保持音视频同步。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.测试拿过来个视频,发现用ijk播放器与系统播放器(mediaplayer)播放感觉不一样,用ijk播放感觉播放页面卡顿一点,没有系统播放器那么流畅。

下面看一下这个问题,这个问题的原因其实很简单,由于我丢帧值设置的是5,改成1就可以感觉2个播放器在体验上感觉差不多了。(丢5帧人眼就可以看出来差别了!)。

2.在高通660的机器上播放一个4k(30fps)视频,但是无法正常播放,实际一秒的解码帧只有20帧,实际播放只有4帧这样。导致画面卡顿,音视频不同步。

后面发现是由于这个视频,在高通机器上很多帧解码都比较慢,导致视频一直比音频慢,在硬解码丢帧时,判断视频一直比音频慢,导致视频一直在丢帧,也就出现看上去的卡顿。

丢帧原理

首先需要明白丢帧需要丢哪里的帧,丢什么帧呢?

丢帧可以丢解码前的帧也可以丢解码后的帧,

丢解码前的帧需要判断帧类型来丢,可以选择丢b,p帧,如果需要丢I帧就需要把整个gop全部丢掉防止花屏。

丢解码后的帧可以不用按照帧类型来丢,由于帧都是解码后的数据了,如yuv,直接按照pts来判断音视频是否不同步来丢就可以了。

1.ffplay中丢帧设计

我们看下ffplay中丢帧的设计:ffplay丢的是解码后的视频帧

在video_thread解码线程中,我们可以看到get_video_frame函数主要用于解码获取解码后的数据avframe,然后来检测判断丢帧。

static int get_video_frame(VideoState *is, AVFrame *frame)
{
    int got_picture;
    //解码获取解码后的数据avframe
    if ((got_picture = decoder_decode_frame(&is->viddec, frame, NULL)) < 0)
        return -1;

    if (got_picture) {
        double dpts = NAN;
        
        if (frame->pts != AV_NOPTS_VALUE)
            dpts = av_q2d(is->video_st->time_base) * frame->pts;//视频的pts转换为ms,也就是当前进度时间
		//视频的宽高比
        frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
        //丢帧数大于0且同步不是按照video
        if (framedrop>0 || (framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) {
        
            if (frame->pts != AV_NOPTS_VALUE) {
               //frame_last_filter_delay 默认是0
               //diff小于0,视频比音频慢,丢帧
               //diff大于0,视频比音频快,不丢帧
                double diff = dpts - get_master_clock(is);
                // AV_NOSYNC_THRESHOLD:同步阈值。如果误差太大,则不进行校正,也不丢帧来做同步了
                if (!isnan(diff) && fabs(diff) < AV_NOSYNC_THRESHOLD &&
                    diff - is->frame_last_filter_delay < 0 &&
                    is->viddec.pkt_serial == is->vidclk.serial &&
                    is->videoq.nb_packets) {
                    is->frame_drops_early++;
          
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值