码控-macroblock_tree_propagate()

/*
	计算帧b的propagate_cost,并瓜分到其参考帧中

	average_duration	当前这一组用于mb tree计算的帧的平均帧时间(s)
	p0,p1,b				前向参考帧、后向参考帧、当前帧
	referenced			是否是参考帧

	过程:
		1.取帧b前向参考帧和后向参考帧的propagate_cost
		2.计算参考的距离因子dist_scale_factor
		3.取帧b的前后向运动向量mvs
		4.根据距离因子计算双向预测的权重bipred_weights[2]
		5.取帧b的propagate_in
		6.取帧b以p0为前向参考,p1为后向参考的satd
		7.计算帧b的fps_factor,即帧b的duration与mb_tree帧组的average_duration的比值
		8.迭代帧b的每一行
			1.根据propagate_in、satd、fps_factor和宏块的intra_cost来计算一行中每个宏块的propagate_cost
			2.根据bipred_weights、mvs将计算的每个宏块propagate_cost瓜分到前后参考帧的propagate_cost中
		9.若是参考帧,则将其propogate_cost变现成qp_offset
*/
static void macroblock_tree_propagate( x264_t *h, x264_frame_t **frames, float average_duration, int p0, int p1, int b, int referenced )
{
	//取前向后向参考帧p0p1的i_propagate_cost
    uint16_t *ref_costs[2] = {frames[p0]->i_propagate_cost,frames[p1]->i_propagate_cost};

	//计算距离因子
    int dist_scale_factor = ( ((b-p0) << 8) + ((p1-p0) >> 1) ) / (p1-p0);

	//取前向后向参考帧p0p1的mv
    int16_t (*mvs[2])[2] = { frames[b]->lowres_mvs[0][b-p0-1], frames[b]->lowres_mvs[1][p1-b-1] };

	//得到双向预测权重
	int i_bipred_weight = h->param.analyse.b_weighted_bipred ? 64 - (dist_scale_factor >> 2) : 32;
    int bipred_weights[2] = {i_bipred_weight, 64 - i_bipred_weight};

	//取帧b的i_propagate_cost,即propagate_in
    uint16_t *propagate_cost = frames[b]->i_propagate_cost;

	//取帧b以p0为前向参考,p1为后向参考的satd
    uint16_t *lowres_costs = frames[b]->lowres_costs[b-p0][p1-b];

	//取buffer用于存储计算的propagate_cost
	int16_t *buf = h->scratch_buffer;

    x264_emms();

	//当前帧的duration/这一组mb tree计算帧的评价duration
    float fps_factor = CLIP_DURATION(frames[b]->f_duration) / (CLIP_DURATION(average_duration) * 256.0f) * MBTREE_PRECISION;

    /* For non-referenced frames the source costs are always zero, so just memset one row and re-use it. 
		非参考帧的i_propagate_cost为0,只设第一行,重复使用
	*/
    if( !referenced )
        memset( frames[b]->i_propagate_cost, 0, h->mb.i_mb_width * sizeof(uint16_t) );

    for( h->mb.i_mb_y = 0; h->mb.i_mb_y < h->mb.i_mb_height; h->mb.i_mb_y++ )//遍历每一行
    {
		//得到每行的起始宏块索引
        int mb_index = h->mb.i_mb_y*h->mb.i_mb_stride;

		//计算一行的propagate_cost到buf中
        h->mc.mbtree_propagate_cost( buf, propagate_cost,
            frames[b]->i_intra_cost+mb_index, lowres_costs+mb_index,
            frames[b]->i_inv_qscale_factor+mb_index, &fps_factor, h->mb.i_mb_width );
		
		/*若是参考帧,则更新一下propagate_cost为下一行
			非参考帧不用更新,反正都是0,重复使用第一行就ok	*/
        if( referenced )
            propagate_cost += h->mb.i_mb_width;

		//将当前帧宏块行计算得到的propagate_cost瓜分到前向参考帧中
        h->mc.mbtree_propagate_list( h, ref_costs[0], &mvs[0][mb_index], buf, &lowres_costs[mb_index],
                                     bipred_weights[0], h->mb.i_mb_y, h->mb.i_mb_width, 0 );
       
		//若存在后向参考,则将当前宏块行计算得到的propagate_cost瓜分到后向参考帧中
		if( b != p1 )
        {
            h->mc.mbtree_propagate_list( h, ref_costs[1], &mvs[1][mb_index], buf, &lowres_costs[mb_index],
                                         bipred_weights[1], h->mb.i_mb_y, h->mb.i_mb_width, 1 );
        }
    }

	/* 若使用了vbv && 使用了码控lookshead && 帧b是参考帧
	   则将该帧的propagate_cost变现成qp_offset	 */
    if( h->param.rc.i_vbv_buffer_size && h->param.rc.i_lookahead && referenced )
        macroblock_tree_finish( h, frames[b], average_duration, b == p1 ? b - p0 : 0 );
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值