📄 umc_h264_crc.cpp
字号:
/*// INTEL CORPORATION PROPRIETARY INFORMATION// This software is supplied under the terms of a license agreement or// nondisclosure agreement with Intel Corporation and may not be copied// or disclosed except in accordance with the terms of that agreement.// Copyright (c) 2004 - 2005 Intel Corporation. All Rights Reserved.*/#include "umc_h264_crc.h"#include "math.h"#include "stdio.h"#include "umc_h264_video_encoder.h"namespace UMC{RateMacroblock RMDef;#define debug_file "rc_debug.txt"#define debug_file_mb "rc_debug_mb.txt"#define debug_file_mb_q "rc_debug_mb_q.txt"#define debug_file_buf "rc_debug_buf.txt"char rc_debug_temp[4096];#undef COLLECT_MVSinline void rc_print_stat(char *string){ FILE *fp=fopen(debug_file,"a+t"); if (fp) { fputs(string,fp); fclose(fp); }}inline void rc_print_stat_mb(char *string){ FILE *fp=fopen(debug_file_mb,"a+t"); if (fp) { fputs(string,fp); fclose(fp); }}inline void rc_print_stat_mb_q(char *string){ FILE *fp=fopen(debug_file_mb_q,"a+t"); if (fp) { fputs(string,fp); fclose(fp); }}inline void rc_print_stat_mb_buf(char *string){ FILE *fp=fopen(debug_file_buf,"a+t"); if (fp) { fputs(string,fp); fclose(fp); }}//#define QUANT_LOG#define RCDebug(x)#define RCDebugMB(x)#define RCDebugMBQ(x)#define RCDebugBuf(x)#ifdef _DEBUG #ifdef QUANT_LOG #undef RCDebug #undef RCDebugMB #undef RCDebugMBQ #undef RCDebugBuf #define RCDebug(x) {sprintf x;rc_print_stat(rc_debug_temp);}; #define RCDebugMB(x) {sprintf x;rc_print_stat_mb(rc_debug_temp);}; #define RCDebugMBQ(x) {sprintf x;rc_print_stat_mb_q(rc_debug_temp);}; #define RCDebugBuf(x) {sprintf x;rc_print_stat_mb_buf(rc_debug_temp);}; #endif#endifstatic Ipp32u solve_quant_equation( RDModel& model, Ipp32u target_bits, Ipp32u complexity ){ Ipp64f tmp_frame_guant; Ipp32u E = complexity; Ipp32u R = target_bits; if ( model.X2 == 0 || ( SQR(model.X1 * E) + 4 * model.X2 * E * R ) < 0 ) { tmp_frame_guant = model.X11 * E / R; } else { tmp_frame_guant = 2*model.X2*E / ( sqrt( SQR(model.X1*E) + 4*model.X2*E*R ) - model.X1*E ); } return (Ipp32u) (tmp_frame_guant + .5);}static void Estimator( Ipp32s wind_size, Ipp64f threshold, Ipp64f* frm_quant_errors, RDModel& model ){ Ipp32s i, tmp; Ipp32s real_wind_size; int frame_quants_differ; tmp = (model.Q.q_get_last()); frame_quants_differ = 0; real_wind_size = 0; model.X11 = 0.; for(i=0; i<wind_size; i++) { Ipp64f Yi; Ipp32s Qi, Ri, Ei; if( fabs(frm_quant_errors[i]) > threshold ) continue; real_wind_size++; Qi = model.Q.q_get(i); Ri = model.R.q_get(i); Ei = model.E.q_get(i); frame_quants_differ |= (tmp!=Qi); Yi = (Ipp64f)Qi * Ri / Ei; model.X11 += Yi; } model.X11 /= real_wind_size; if(frame_quants_differ) { /* x2[frame_type] = ( n * SUM(Ri/Ei) - SUM(1/Qi) * SUM(Qi*Ri/Ei) ) / (n * SUM(1/SQR(Qi)) - SQR(SUM(1/Qi))) x1[frame_type] = SUM(Qi*Ri/Ei - x2[frame_type]/Qi) / n */ Ipp64f S_R_div_E = 0., S_Q_mul_R_div_E = 0., S_1_div_Q = 0., S_1_div_QQ = 0.; /* x2[frame_type] */ for(i=0; i<wind_size; i++) { Ipp64f tmp1, tmp2; if( fabs(frm_quant_errors[i]) > threshold ) continue; tmp1 = 1. / model.Q.q_get(i); S_1_div_Q += tmp1; S_1_div_QQ += SQR(tmp1); tmp2 = (Ipp64f)model.R.q_get( i) / model.E.q_get(i); S_R_div_E += tmp2; S_Q_mul_R_div_E += model.Q.q_get(i) * tmp2; } if( fabs(real_wind_size * S_1_div_QQ - SQR(S_1_div_Q)) < 1e-10) model.X2 = 0.; else model.X2 = ( real_wind_size * S_R_div_E - S_1_div_Q * S_Q_mul_R_div_E ) / ( real_wind_size * S_1_div_QQ - SQR(S_1_div_Q) ); /* x1[frame_type] */ model.X1 = (S_Q_mul_R_div_E - model.X2 * S_1_div_Q) / real_wind_size; }}static void RD_update_mb( RDModel& model ){ Ipp64f quant_errors[HISTORY_SIZE]; /* to remove outliers */ Ipp64f threshold; Ipp32s i; Ipp32s wind_size; wind_size = model.Q.cur_data_count; model.X11 = model.X1 = model.X2 = 0.; /* estimator */ threshold = 1.; memset( &quant_errors, 0, sizeof(quant_errors[0])*HISTORY_SIZE ); Estimator(wind_size, threshold, &quant_errors[0], model); /* RemoveOutlier */ if(wind_size>2) { threshold = 0.; for (i=0; i<wind_size; i++) { quant_errors[i] = ( model.X1/model.Q.q_get(i) + model.X2/SQR(model.Q.q_get(i)) ) * model.E.q_get_last() - model.R.q_get(i); threshold += SQR( quant_errors[i] ); } threshold = sqrt( threshold / wind_size ); /* estimator-2 */ Estimator(wind_size, threshold, &quant_errors[0], model); } return;}static void RD_update_frm( Ipp32s wind_size, RDModel& model ){ Ipp64f frm_quant_errors[HISTORY_SIZE]; /* to remove outliers */ Ipp64f threshold; Ipp32s i; model.X11 = model.X1 = model.X2 = 0.; /* estimator */ threshold = 1.; memset( &frm_quant_errors, 0, sizeof(frm_quant_errors[0])*HISTORY_SIZE ); Estimator( wind_size, threshold, &frm_quant_errors[0], model ); /* RemoveOutlier */ if(wind_size>2) { threshold = 0.; for (i=0; i<wind_size; i++) { frm_quant_errors[i] = ( model.X1/model.Q.q_get(i) + model.X2/SQR(model.Q.q_get(i)) ) * model.E.q_get_last() - model.R.q_get( i); threshold += SQR( frm_quant_errors[i] ); } threshold = sqrt( threshold / wind_size ); /* estimator-2 */ Estimator( wind_size, threshold, &frm_quant_errors[0], model ); } return;}Ipp32u CH264ConstRateControl::UpdateMBComplexity(Ipp32u number){ mbs[number].mb_complexity=mbs[number].mb_sum=0; int y=(number/width_mb)*16,x=(number%width_mb)*16; int h; for (h=0;h<16;h++) { for (int w=0;w<16;w++) { int index=(y+h)*pitch+(x+w); mbs[number].mb_sum += cur_y_plane[index]; } } for (h=0;h<16;h++) { for (int w=0;w<16;w++) { int index=(y+h)*pitch+(x+w); Ipp32s abs_diff; abs_diff = abs( cur_y_plane[index] - (Ipp32s)(mbs[number].mb_sum>>8) ); mbs[number].mb_complexity+= abs_diff; } } return MB_COMPLEXITY(number);}void CH264ConstRateControl::CalculateComplexity2(H264Extra_MB_Info *ExMBInfo){ Ipp32u i; for(i=0; i<mb_count ; i++) { //mbs[i].mb_complexity = ExMBInfo[i].MB_Intra_SAD; mbs[i].mb_sad = ExMBInfo[i].MB_Inter_SAD; mbs[i].type = ExMBInfo[i].MB_Mode; }}Ipp32u CH264ConstRateControl::CalculateComplexity(){ Ipp32u i, j, index; Ipp64s ret_val=0; for(i=0;i<mb_count; i++) mbs[i]=RMDef; //defaulting macroblocks for(i=0; i<height; i++) { for(j=0; j<width; j++) { Ipp32s mb_num = (i>>4)*width_mb + (j>>4); index = i*pitch+j; mbs[mb_num].mb_sum += cur_y_plane[index]; } } for(i=0; i<height; i++) { for(j=0; j<width; j++) { Ipp32s abs_diff; Ipp32s mb_num = (i>>4)*width_mb + (j>>4); index = i*pitch+j; abs_diff = abs( cur_y_plane[index] - (Ipp32s)(mbs[mb_num].mb_sum>>8) ); /* we assume macroblock_complexity to be filled with zero before calculation */ mbs[mb_num].mb_complexity+= abs_diff; ret_val += abs_diff; } } ret_val = ret_val *(1<<10) / (width_mb * height_mb) + 1; return (Ipp32u)ret_val;}#define IDEAL_PERCENTAGE 0.95#define MIN_CRITICAL_PERCENTAGE min_frs#define MAX_CRITICAL_PERCENTAGE max_frs#define AIF_CC1_1 3#define AIF_CC1_2 1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -