📄 umc_h264_crc.cpp
字号:
#define AIF_CC1_A 4#define AIF_CC2_1 2#define AIF_CC2_2 1#define AIF_CC2_A 3#define AIF_CC3_1 1#define AIF_CC3_2 1#define AIF_CC3_A 2#define AIF_CC4_1 1#define AIF_CC4_2 2#define AIF_CC4_A 3#define AIF_CC5_1 1#define AIF_CC5_2 3#define AIF_CC5_A 4#define MAX_CC 5Ipp32u CC_1_table[MAX_CC]={AIF_CC1_1,AIF_CC2_1,AIF_CC3_1,AIF_CC4_1,AIF_CC5_1};Ipp32u CC_2_table[MAX_CC]={AIF_CC1_2,AIF_CC2_2,AIF_CC3_2,AIF_CC4_2,AIF_CC5_2};Ipp32u CC_A_table[MAX_CC]={AIF_CC1_A,AIF_CC2_A,AIF_CC3_A,AIF_CC4_A,AIF_CC5_A};Ipp32u CH264ConstRateControl::PictureRateControl( Ipp8u *y_plane,Ipp8u *u_plane,Ipp8u *v_plane, Ipp32u frame_number, Ipp32u frame_type, Ipp64s bits_encoded, H264Extra_MB_Info *ExMBInfo, double start_frame_time,double stop_frame_time){ Ipp32s frm_bits_estimated; cur_y_plane=y_plane; cur_u_plane=u_plane; cur_v_plane=v_plane; cur_frame_number = frame_number; cur_frame_type = (Ipp8u)frame_type; Ipp32s frame_complexity=0; Ipp32u ideal_bits_encoded; Ipp32s ideal_queue_bits; start_bits_encoded=bits_encoded; if(frame_type== INTRAPIC) //intra frame_complexity = CalculateComplexity();#ifdef COLLECT_MVS else CalculateComplexity2(ExMBInfo);#endif frm_mbs_skipped = 0; last_mb_number = -1; last_frm_bit_pos=bits_encoded; if (frame_number==0) { init_frame_time=start_frame_time; } if (cur_frame_type==INTRAPIC) last_intra_frame = cur_frame_number; ideal_bits_encoded=(Ipp32s)(target_bits_per_second*(stop_frame_time-init_frame_time)); target_bits_per_frame=(Ipp32u)(ideal_bits_encoded/(frame_number+1)); if (frame_number>=queue_size && queue_size) { target_frames_per_second=frame_number/(stop_frame_time-init_frame_time); } frm_bits_estimated = (Ipp32s)((ideal_bits_encoded-bits_encoded)*(IDEAL_PERCENTAGE)+target_bits_per_frame*(1-IDEAL_PERCENTAGE)); if (frm_bits_estimated>target_bits_per_frame*MAX_CRITICAL_PERCENTAGE) frm_bits_estimated=(Ipp32s)(target_bits_per_frame*MAX_CRITICAL_PERCENTAGE); if (queue_size) { if (frame_number%queue_size==1 && frame_number>queue_size) { intra_coded_frames_in_queue=0; queue_start_bits=bits_encoded; queue_bits=(Ipp64s)(target_bits_per_second*queue_size/target_frames_per_second); queue_bits_per_frame=(Ipp32s)queue_bits/queue_size; } } if (frame_number>queue_size && queue_size) { ideal_queue_bits=(Ipp32s)(queue_start_bits+(queue_bits_per_frame)*((frame_number%queue_size))-bits_encoded); //(queue_bits-(queue_bits_per_frame)*(frame_number%queue_size)) // /(queue_size-(frame_number%queue_size)) *MAX_LT_CRITICAL_PERCENTAGE; if (frm_bits_estimated>ideal_queue_bits) frm_bits_estimated=ideal_queue_bits; } Ipp64f min_cr_p; if (cur_frame_number<last_intra_frame+MAX_CC && cur_frame_number>last_intra_frame) { min_cr_p = (CC_1_table[cur_frame_number-last_intra_frame-1]+CC_2_table[cur_frame_number-last_intra_frame-1]*MIN_CRITICAL_PERCENTAGE)/ CC_A_table[cur_frame_number-last_intra_frame-1]; } else { min_cr_p=MIN_CRITICAL_PERCENTAGE; } if (frm_bits_estimated<target_bits_per_frame*MIN_CRITICAL_PERCENTAGE) frm_bits_estimated=(Ipp32s)(target_bits_per_frame*min_cr_p); intra_coded_frames_in_queue+=frame_type==INTRAPIC;#if 1 if( frame_type == INTRAPIC && /* it'a I-frame */ (total_frames_coded > 10 && /* statistics is enough */ frames_coded[0] < (total_frames_coded/i_frames_mult) || cur_frame_number==0) /* I-frames count is less than half of total frames */ ) { frm_bits_estimated = (Ipp32s)(frm_bits_estimated*i_frames_mult); }#endif frm_bits_rest = frm_bits_estimated; if(frames_coded[frame_type]==0) { frame_quant_cur = INITIAL_FRAME_QUANT; RCDebug((rc_debug_temp,"Picture:frm_num %d time %.3lf %.3lf type %d enc at st %I64d est %d\n", cur_frame_number,start_frame_time,stop_frame_time,frame_type,start_bits_encoded,frm_bits_estimated)); return frame_quant_cur; }/* if( frame_type == PREDPIC || frame_type == BPREDPIC ) { Ipp32s i; for( i=width_mb * height_mb - 1; i>=0; i-- ) { mbs[i].max_skip_error = max_skip_error[frame_type]; } }*/ /* We need to do here: 1) target bits estimation 2) quantization parameter calculation */ /* *** bits estimation *** */ /* target bits estimation - ideal_bits(bit_rate, frm-rate) - prev. frame adjustment: trg_bits = ideal_bits(1-PREV_FRM_IMPACT) + prev_frm_bits*PREV_FRM_IMPACT; - CPB adjustment: trg_bits *= ( cpb_bits+2*(cpb_size-cpb_bits) ) / ( 2*cpb_bits+(cpb_size-cpb_bits) ) - min quality: trg_bits = max( bit_rate/frm_rate, trg_bits) - potential buffer overflow and buffer underflow: overflow: if(cpb_bits+trg_bits > (1-cpb_safe_part)*CPB_size) trg_bits = (1-cpb_safe_part)*cpb_size - cpb_bits underflow: if(cpb_bits+trg_bits-bit_rate/frm_rate < cpb_safe_part*cpb_size) trg_bits = bit_rate/frm-rate - cpb_bits + cpb_safe_part*cpb_size*/ /* prev. frame adjustment */ if(frames_coded[frame_type]>0) { frm_bits_estimated = (Ipp32s)(frm_bits_estimated * (1. - PREV_FRM_IMPACT) + model[frame_type].R.q_get_last() * PREV_FRM_IMPACT); } /* CPB adjustment */#if 0 { cpb_bits = max(cpb_bits, 0); cpb_bits = min(cpb_bits, cpb_size<<1); frm_bits_estimated *= (Ipp64f)( cpb_bits + ((cpb_size - cpb_bits)<<1) ) / ( (cpb_bits<<1) + (cpb_size - cpb_bits) ); } /* overflow */ if(cpb_bits+frm_bits_estimated > (1.-CPB_SAFE_PART)*cpb_size) frm_bits_estimated = (1.-CPB_SAFE_PART)*cpb_size - cpb_bits; frm_bits_estimated = max(frm_bits_estimated, 1); /* underflow */ if( cpb_bits + frm_bits_estimated - target_bit_rate/target_frame_rate< CPB_SAFE_PART * cpb_size ) frm_bits_estimated = target_bit_rate/target_frame_rate - cpb_bits + CPB_SAFE_PART*cpb_size;#endif frm_bits_rest = frm_bits_estimated; /* *** quant. param. calculation *** */ if(frame_complexity==0) frame_complexity =model[frame_type].E.q_get_last(); /* approximate by prev. frame value */ frame_quant_cur = solve_quant_equation( model[frame_type], frm_bits_estimated, frame_complexity ); /* clipping*/ frame_quant_cur = min(frame_quant_cur, qp_max); frame_quant_cur = max(frame_quant_cur, qp_min); RCDebug((rc_debug_temp,"Picture:frm_num %d time %.3lf %.3lf type %d enc at st %I64d est %d\n", cur_frame_number,start_frame_time,stop_frame_time,frame_type,start_bits_encoded,frm_bits_estimated)); return frame_quant_cur;}Ipp32u CH264ConstRateControl::PostPictureRateControl(Ipp64s bits_encoded){#if 0 Ipp32s frm_extra_bits = (Ipp32s)((bits_encoded - last_frm_bit_pos) - target_bits_per_frame);#endif Ipp32s frm_size = (Ipp32s)(bits_encoded - last_frm_bit_pos - last_frm_stuffed_bits); Ipp32s wind_size; Ipp64s cur_frm_complexity, last_frm_complexity; Ipp32s bits_stuffed; bits_stuffed = 0; frames_coded[cur_frame_type]++; total_frames_coded++; last_frm_bit_pos = bits_encoded; /* is the frame skipped ? */ /* mb-level */ Ipp32u i, j, index, counter; Ipp64f frame_quant_average; frame_quant_average = 0.; counter = 0; for(i=0, index=0; i<height_mb; i++) { for(j=0; j<width_mb; j++,index++) { if(mbs[index].quant > 0) { counter++; frame_quant_average += mbs[index].quant; } } } frame_quant_average /= counter; frame_quant_cur = (Ipp32s)(frame_quant_average + .5);#if 0 cpb_bits += frm_extra_bits; if( cpb_bits < cpb_size*CPB_SAFE_PART ) { bits_stuffed = cpb_size*CPB_SAFE_PART - cpb_bits; cpb_bits += bits_stuffed; last_frm_stuffed_bits = bits_stuffed; }#else bits_stuffed=frm_bits_rest; if (bits_stuffed<0) bits_stuffed=0; last_frm_stuffed_bits = 0; //if (cur_frame_number==299) RCDebug((rc_debug_temp,"PostPicture:frm_num % d st %d enc %I64d enc at st %I64d actually %I64d\n", cur_frame_number,bits_stuffed,bits_encoded,start_bits_encoded,bits_encoded-start_bits_encoded));#endif /* calc frame complexity */ { Ipp64s complexity = 0; Ipp32u i; for(i=0; i<width_mb * height_mb; i++) complexity += MB_COMPLEXITY(i); cur_frm_complexity = complexity * (1<<10) / (width_mb * height_mb) + 1; /* we assume cur_frm_complexity as average macroblock_complexity in frame * (1<<10), because macroblock_complexity can be from 0 to 32768. + 1 prevent zero value of cur_frm_complexity. */ } /* We need to do here: 1) updating the correspondent quadratic R-D model for the entire frame 2) frame-skipping control */ /* *** R-D model *** */ // STD implementation last_frm_complexity = model[cur_frame_type].E.q_get_last(); model[cur_frame_type].E.q_push_force((Ipp32s)cur_frm_complexity); model[cur_frame_type].Q.q_push_force(frame_quant_cur); model[cur_frame_type].R.q_push_force(frm_size); wind_size = model[cur_frame_type].Q.cur_data_count; if(last_frm_complexity > cur_frm_complexity) wind_size = (Ipp32s)(wind_size * (Ipp64f)cur_frm_complexity/last_frm_complexity); else wind_size = (Ipp32s)(wind_size * (Ipp64f)last_frm_complexity/cur_frm_complexity); if(wind_size==0) wind_size = 1; RD_update_frm( wind_size, model[cur_frame_type] ); /* *** frame skip ctrl (predictive) *** */#if 0 if(cpb_bits + frm_extra_bits > cpb_size*(1-CPB_SAFE_PART)) { total_frm_skipped++; cpb_bits -= target_bit_rate/target_frame_rate; /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -