x264代码学习笔记(三):x264_slicetype_decide函数

x264_slicetype_decide函数在x264编码器中负责分析视频帧类型,包括I、P、B帧,并将播放顺序转换为编码顺序。该函数先由x264_lookahead_get_frames预处理,然后通过x264_slicetype_analyse确定帧类型。过程中考虑了可变帧率、帧成本和码率控制,以优化编码效率。

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

x264_slicetype_decide函数(代码所在位置为“x264-snapshot-20171128-2245-stable\encoder\slicetype.c”)的主要作用为:分析帧类型(I\P\B帧)以及将视频播放序列转换为编码序列

调用顺序如下:

x264_encoder_encode —> x264_lookahead_get_frames —> x264_slicetype_decide

x264_lookahead_get_frames函数:

void x264_lookahead_get_frames( x264_t *h )
{
    if( h->param.i_sync_lookahead )  // 前向考虑帧数
    {   /* We have a lookahead thread, so get frames from there */
        x264_pthread_mutex_lock( &h->lookahead->ofbuf.mutex );
        while( !h->lookahead->ofbuf.i_size && h->lookahead->b_thread_active )
            x264_pthread_cond_wait( &h->lookahead->ofbuf.cv_fill, &h->lookahead->ofbuf.mutex );
        x264_lookahead_encoder_shift( h );
        x264_pthread_mutex_unlock( &h->lookahead->ofbuf.mutex );
    }
    else
    {   /* We are not running a lookahead thread, so perform all the slicetype decide on the fly */

		//currect[]必须为空,next不能为空,next为空意味着没有待确定类型的帧,后面就没必要进行帧类型分析了 
        if( h->frames.current[0] || !h->lookahead->next.i_size )
            return;

		//分析lookahead->next->list帧的类型  
        x264_stack_align( x264_slicetype_decide, h ); // x264_slicetype_decide()用于确定帧类型
        //更新lookahead->last_nonb 
        x264_lookahead_update_last_nonb( h, h->lookahead->next.list[0] );  // 更新最后一个非B帧
        int shift_frames = h->lookahead->next.list[0]->i_bframes + 1;      // 计算需要移动的帧数
		//将lookahead->next.list中最左边shift_frames个帧移动到lookahead->ofbuf.list 
        x264_lookahead_shift( &h->lookahead->ofbuf, &h->lookahead->next, shift_frames );

        /* For MB-tree and VBV lookahead, we have to perform propagation analysis on I-frames too. */
        if( h->lookahead->b_analyse_keyframe && IS_X264_TYPE_I( h->lookahead->last_nonb->i_type ) )
            x264_stack_align( x264_slicetype_analyse, h, shift_frames );   // 分析帧类型

		//lookahead->ofbuf.list帧移动到frames->current 
        x264_lookahead_encoder_shift( h );
    }
}

x264_slicetype_decide函数:

  1. 首先,h->lookahead->next.list为待确定帧类型列表,一般存储至少一个GOP的帧数;
  2. 遍历h->lookahead->next.list链表,针对是否为可变帧率对duration以及其他参数进行赋值;
  3. 通过x264_slicetype_analyse函数对视频帧进行类型确认,确认是I帧还是P帧或者B帧等;
  4. 遍历分析h->lookahead->next.list链表,获取B帧(包括参考和非参考B帧)的个数和参考型B帧的个数;
  5. 根据不同的码率控制计算其帧代价,为后续帧内/帧间模式选择等做准备;
  6. 将播放序列转换为编码序列,方便后续的编码工作;
  7. 对durations等参数进行更新。
//分析帧的类型(I、B、P) 以及将播放序列转换为编码序列等功能 
void x264_slicetype_decide( x264_t *h )
{
    x264_frame_t *frames[X264_BFRAME_MAX+2]; //
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lifei092

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值