void targetBitCalculation(void *input) { VideoEncData *video = (VideoEncData *) input; MultiPass *pMP = video->pMP[video->currLayer]; Vol *currVol = video->vol[video->currLayer]; rateControl *rc = video->rc[video->currLayer]; float curr_mad;//, average_mad; Int diff_counter_BTsrc, diff_counter_BTdst, prev_counter_diff, curr_counter_diff, bound; /* BT = Bit Transfer, for pMP->counter_BTsrc, pMP->counter_BTdst */ if (video == NULL || currVol == NULL || pMP == NULL || rc == NULL) return; /* some stuff about frame dropping remained here to be done because pMP cannot be inserted into updateRateControl()*/ updateRC_PostProc(rc, video); /* update pMP->counter_BTsrc and pMP->counter_BTdst to avoid interger overflow */ if (pMP->counter_BTsrc > 1000 && pMP->counter_BTdst > 1000) { pMP->counter_BTsrc -= 1000; pMP->counter_BTdst -= 1000; } /* ---------------------------------------------------------------------------------------------------*/ /* target calculation */ curr_mad = video->sumMAD / (float)currVol->nTotalMB; if (curr_mad < MAD_MIN) curr_mad = MAD_MIN; /* MAD_MIN is defined as 1 in mp4def.h */ diff_counter_BTsrc = diff_counter_BTdst = 0; pMP->diff_counter = 0; /*1.calculate average mad */ pMP->sum_mad += curr_mad; //average_mad = (pMP->encoded_frames < 1 ? curr_mad : pMP->sum_mad/(float)(pMP->encoded_frames+1)); /* this function is called from the scond encoded frame*/ //pMP->aver_mad = average_mad; if (pMP->encoded_frames >= 0) /* pMP->encoded_frames is set to -1 initially, so forget about the very first I frame */ pMP->aver_mad = (pMP->aver_mad * pMP->encoded_frames + curr_mad) / (pMP->encoded_frames + 1); if (pMP->overlapped_win_size > 0 && pMP->encoded_frames_prev >= 0) /* 7/31/03 */ pMP->aver_mad_prev = (pMP->aver_mad_prev * pMP->encoded_frames_prev + curr_mad) / (pMP->encoded_frames_prev + 1); /*2.average_mad, mad ==> diff_counter_BTsrc, diff_counter_BTdst */ if (pMP->overlapped_win_size == 0) { /* original verison */ if (curr_mad > pMP->aver_mad*1.1) { if (curr_mad / (pMP->aver_mad + 0.0001) > 2) diff_counter_BTdst = (Int)(M4VENC_SQRT(curr_mad / (pMP->aver_mad + 0.0001)) * 10 + 0.4) - 10; //diff_counter_BTdst = (Int)((sqrt(curr_mad/pMP->aver_mad)*2+curr_mad/pMP->aver_mad)/(3*0.1) + 0.4) - 10; else diff_counter_BTdst = (Int)(curr_mad / (pMP->aver_mad + 0.0001) * 10 + 0.4) - 10; } else /* curr_mad <= average_mad*1.1 */ //diff_counter_BTsrc = 10 - (Int)((sqrt(curr_mad/pMP->aver_mad) + pow(curr_mad/pMP->aver_mad, 1.0/3.0))/(2.0*0.1) + 0.4); diff_counter_BTsrc = 10 - (Int)(M4VENC_SQRT(curr_mad / (pMP->aver_mad + 0.0001)) * 10 + 0.5); //diff_counter_BTsrc = 10 - (Int)(curr_mad/pMP->aver_mad/0.1 + 0.5) /* actively fill in the possible gap */ if (diff_counter_BTsrc == 0 && diff_counter_BTdst == 0 && curr_mad <= pMP->aver_mad*1.1 && pMP->counter_BTsrc < pMP->counter_BTdst) diff_counter_BTsrc = 1; } else if (pMP->overlapped_win_size > 0) { /* transition time: use previous average mad "pMP->aver_mad_prev" instead of the current average mad "pMP->aver_mad" */ if (curr_mad > pMP->aver_mad_prev*1.1) { if (curr_mad / pMP->aver_mad_prev > 2) diff_counter_BTdst = (Int)(M4VENC_SQRT(curr_mad / (pMP->aver_mad_prev + 0.0001)) * 10 + 0.4) - 10; //diff_counter_BTdst = (Int)((M4VENC_SQRT(curr_mad/pMP->aver_mad_prev)*2+curr_mad/pMP->aver_mad_prev)/(3*0.1) + 0.4) - 10; else diff_counter_BTdst = (Int)(curr_mad / (pMP->aver_mad_prev + 0.0001) * 10 + 0.4) - 10; } else /* curr_mad <= average_mad*1.1 */ //diff_counter_BTsrc = 10 - (Int)((sqrt(curr_mad/pMP->aver_mad_prev) + pow(curr_mad/pMP->aver_mad_prev, 1.0/3.0))/(2.0*0.1) + 0.4); diff_counter_BTsrc = 10 - (Int)(M4VENC_SQRT(curr_mad / (pMP->aver_mad_prev + 0.0001)) * 10 + 0.5); //diff_counter_BTsrc = 10 - (Int)(curr_mad/pMP->aver_mad_prev/0.1 + 0.5) /* actively fill in the possible gap */ if (diff_counter_BTsrc == 0 && diff_counter_BTdst == 0 && curr_mad <= pMP->aver_mad_prev*1.1 && pMP->counter_BTsrc < pMP->counter_BTdst) diff_counter_BTsrc = 1; if (--pMP->overlapped_win_size <= 0) pMP->overlapped_win_size = 0; } /* if difference is too much, do clipping */ /* First, set the upper bound for current bit allocation variance: 80% of available buffer */ bound = (Int)((rc->Bs / 2 - rc->VBV_fullness) * 0.6 / (pMP->target_bits_per_frame / 10)); /* rc->Bs */ diff_counter_BTsrc = PV_MIN(diff_counter_BTsrc, bound); diff_counter_BTdst = PV_MIN(diff_counter_BTdst, bound); /* Second, set another upper bound for current bit allocation: 4-5*bitrate/framerate */ bound = 50; // if(video->encParams->RC_Type == CBR_LOWDELAY) // not necessary bound = 10; /* 1/17/02 -- For Low delay */ diff_counter_BTsrc = PV_MIN(diff_counter_BTsrc, bound); diff_counter_BTdst = PV_MIN(diff_counter_BTdst, bound); /* Third, check the buffer */ prev_counter_diff = pMP->counter_BTdst - pMP->counter_BTsrc; curr_counter_diff = prev_counter_diff + (diff_counter_BTdst - diff_counter_BTsrc); if (PV_ABS(prev_counter_diff) >= rc->max_BitVariance_num || PV_ABS(curr_counter_diff) >= rc->max_BitVariance_num) // PV_ABS(curr_counter_diff) >= PV_ABS(prev_counter_diff) ) { //diff_counter_BTsrc = diff_counter_BTdst = 0; if (curr_counter_diff > rc->max_BitVariance_num && diff_counter_BTdst) { diff_counter_BTdst = (rc->max_BitVariance_num - prev_counter_diff) + diff_counter_BTsrc; if (diff_counter_BTdst < 0) diff_counter_BTdst = 0; } else if (curr_counter_diff < -rc->max_BitVariance_num && diff_counter_BTsrc) { diff_counter_BTsrc = diff_counter_BTdst - (-rc->max_BitVariance_num - prev_counter_diff); if (diff_counter_BTsrc < 0) diff_counter_BTsrc = 0; } } /*3.diff_counter_BTsrc, diff_counter_BTdst ==> TMN_TH */ //rc->TMN_TH = (Int)((float)pMP->bitrate/pMP->framerate); rc->TMN_TH = (Int)(pMP->target_bits_per_frame); pMP->diff_counter = 0; if (diff_counter_BTsrc) { rc->TMN_TH -= (Int)(pMP->target_bits_per_frame * diff_counter_BTsrc * 0.1); pMP->diff_counter = -diff_counter_BTsrc; } else if (diff_counter_BTdst) { rc->TMN_TH += (Int)(pMP->target_bits_per_frame * diff_counter_BTdst * 0.1); pMP->diff_counter = diff_counter_BTdst; } /*4.update pMP->counter_BTsrc, pMP->counter_BTdst */ pMP->counter_BTsrc += diff_counter_BTsrc; pMP->counter_BTdst += diff_counter_BTdst; /*5.target bit calculation */ rc->T = rc->TMN_TH - rc->TMN_W; //rc->T = rc->TMN_TH - (Int)((float)rc->TMN_W/rc->frameRate); if (video->encParams->H263_Enabled && rc->T > video->encParams->maxFrameSize) { rc->T = video->encParams->maxFrameSize; // added this 11/07/05 } }
void targetBitCalculation(AVCEncObject *encvid, AVCCommonObj *video, AVCRateControl *rateCtrl, MultiPass *pMP) { OSCL_UNUSED_ARG(encvid); OsclFloat curr_mad;//, average_mad; int diff_counter_BTsrc, diff_counter_BTdst, prev_counter_diff, curr_counter_diff, bound; /* BT = Bit Transfer, for pMP->counter_BTsrc, pMP->counter_BTdst */ /* some stuff about frame dropping remained here to be done because pMP cannot be inserted into updateRateControl()*/ updateRC_PostProc(rateCtrl, pMP); /* update pMP->counter_BTsrc and pMP->counter_BTdst to avoid interger overflow */ if (pMP->counter_BTsrc > 1000 && pMP->counter_BTdst > 1000) { pMP->counter_BTsrc -= 1000; pMP->counter_BTdst -= 1000; } /* ---------------------------------------------------------------------------------------------------*/ /* target calculation */ curr_mad = (OsclFloat)rateCtrl->totalSAD / video->PicSizeInMbs; if (curr_mad < MAD_MIN) curr_mad = MAD_MIN; /* MAD_MIN is defined as 1 in mp4def.h */ diff_counter_BTsrc = diff_counter_BTdst = 0; pMP->diff_counter = 0; /*1.calculate average mad */ pMP->sum_mad += curr_mad; //average_mad = (pMP->encoded_frames < 1 ? curr_mad : pMP->sum_mad/(OsclFloat)(pMP->encoded_frames+1)); /* this function is called from the scond encoded frame*/ //pMP->aver_mad = average_mad; if (pMP->encoded_frames >= 0) /* pMP->encoded_frames is set to -1 initially, so forget about the very first I frame */ pMP->aver_mad = (pMP->aver_mad * pMP->encoded_frames + curr_mad) / (pMP->encoded_frames + 1); if (pMP->overlapped_win_size > 0 && pMP->encoded_frames_prev >= 0) pMP->aver_mad_prev = (pMP->aver_mad_prev * pMP->encoded_frames_prev + curr_mad) / (pMP->encoded_frames_prev + 1); /*2.average_mad, mad ==> diff_counter_BTsrc, diff_counter_BTdst */ if (pMP->overlapped_win_size == 0) { /* original verison */ if (curr_mad > pMP->aver_mad*1.1) { if (curr_mad / (pMP->aver_mad + 0.0001) > 2) diff_counter_BTdst = (int)(oscl_sqrt(curr_mad / (pMP->aver_mad + 0.0001)) * 10 + 0.4) - 10; //diff_counter_BTdst = (int)((sqrt(curr_mad/pMP->aver_mad)*2+curr_mad/pMP->aver_mad)/(3*0.1) + 0.4) - 10; else diff_counter_BTdst = (int)(curr_mad / (pMP->aver_mad + 0.0001) * 10 + 0.4) - 10; } else /* curr_mad <= average_mad*1.1 */ //diff_counter_BTsrc = 10 - (int)((sqrt(curr_mad/pMP->aver_mad) + pow(curr_mad/pMP->aver_mad, 1.0/3.0))/(2.0*0.1) + 0.4); diff_counter_BTsrc = 10 - (int)(oscl_sqrt(curr_mad / (pMP->aver_mad + 0.0001)) * 10 + 0.5); /* actively fill in the possible gap */ if (diff_counter_BTsrc == 0 && diff_counter_BTdst == 0 && curr_mad <= pMP->aver_mad*1.1 && pMP->counter_BTsrc < pMP->counter_BTdst) diff_counter_BTsrc = 1; } else if (pMP->overlapped_win_size > 0) { /* transition time: use previous average mad "pMP->aver_mad_prev" instead of the current average mad "pMP->aver_mad" */ if (curr_mad > pMP->aver_mad_prev*1.1) { if (curr_mad / pMP->aver_mad_prev > 2) diff_counter_BTdst = (int)(oscl_sqrt(curr_mad / (pMP->aver_mad_prev + 0.0001)) * 10 + 0.4) - 10; //diff_counter_BTdst = (int)((M4VENC_SQRT(curr_mad/pMP->aver_mad_prev)*2+curr_mad/pMP->aver_mad_prev)/(3*0.1) + 0.4) - 10; else diff_counter_BTdst = (int)(curr_mad / (pMP->aver_mad_prev + 0.0001) * 10 + 0.4) - 10; } else /* curr_mad <= average_mad*1.1 */ //diff_counter_BTsrc = 10 - (Int)((sqrt(curr_mad/pMP->aver_mad_prev) + pow(curr_mad/pMP->aver_mad_prev, 1.0/3.0))/(2.0*0.1) + 0.4); diff_counter_BTsrc = 10 - (int)(oscl_sqrt(curr_mad / (pMP->aver_mad_prev + 0.0001)) * 10 + 0.5); /* actively fill in the possible gap */ if (diff_counter_BTsrc == 0 && diff_counter_BTdst == 0 && curr_mad <= pMP->aver_mad_prev*1.1 && pMP->counter_BTsrc < pMP->counter_BTdst) diff_counter_BTsrc = 1; if (--pMP->overlapped_win_size <= 0) pMP->overlapped_win_size = 0; } /* if difference is too much, do clipping */ /* First, set the upper bound for current bit allocation variance: 80% of available buffer */ bound = (int)((rateCtrl->Bs / 2 - rateCtrl->VBV_fullness) * 0.6 / (pMP->target_bits_per_frame / 10)); /* rateCtrl->Bs */ diff_counter_BTsrc = AVC_MIN(diff_counter_BTsrc, bound); diff_counter_BTdst = AVC_MIN(diff_counter_BTdst, bound); /* Second, set another upper bound for current bit allocation: 4-5*bitrate/framerate */ bound = 50; // if(video->encParams->RC_Type == CBR_LOWDELAY) // not necessary bound = 10; -- For Low delay */ diff_counter_BTsrc = AVC_MIN(diff_counter_BTsrc, bound); diff_counter_BTdst = AVC_MIN(diff_counter_BTdst, bound); /* Third, check the buffer */ prev_counter_diff = pMP->counter_BTdst - pMP->counter_BTsrc; curr_counter_diff = prev_counter_diff + (diff_counter_BTdst - diff_counter_BTsrc); if (AVC_ABS(prev_counter_diff) >= rateCtrl->max_BitVariance_num || AVC_ABS(curr_counter_diff) >= rateCtrl->max_BitVariance_num) { //diff_counter_BTsrc = diff_counter_BTdst = 0; if (curr_counter_diff > rateCtrl->max_BitVariance_num && diff_counter_BTdst) { diff_counter_BTdst = (rateCtrl->max_BitVariance_num - prev_counter_diff) + diff_counter_BTsrc; if (diff_counter_BTdst < 0) diff_counter_BTdst = 0; } else if (curr_counter_diff < -rateCtrl->max_BitVariance_num && diff_counter_BTsrc) { diff_counter_BTsrc = diff_counter_BTdst - (-rateCtrl->max_BitVariance_num - prev_counter_diff); if (diff_counter_BTsrc < 0) diff_counter_BTsrc = 0; } } /*3.diff_counter_BTsrc, diff_counter_BTdst ==> TMN_TH */ rateCtrl->TMN_TH = (int)(pMP->target_bits_per_frame); pMP->diff_counter = 0; if (diff_counter_BTsrc) { rateCtrl->TMN_TH -= (int)(pMP->target_bits_per_frame * diff_counter_BTsrc * 0.1); pMP->diff_counter = -diff_counter_BTsrc; } else if (diff_counter_BTdst) { rateCtrl->TMN_TH += (int)(pMP->target_bits_per_frame * diff_counter_BTdst * 0.1); pMP->diff_counter = diff_counter_BTdst; } /*4.update pMP->counter_BTsrc, pMP->counter_BTdst */ pMP->counter_BTsrc += diff_counter_BTsrc; pMP->counter_BTdst += diff_counter_BTdst; /*5.target bit calculation */ rateCtrl->T = rateCtrl->TMN_TH - rateCtrl->TMN_W; return ; }
PV_STATUS RC_UpdateBXRCParams(void *input) { VideoEncData *video = (VideoEncData *) input; VideoEncParams *encParams = video->encParams; rateControl **rc = video->rc; Int numLayers = encParams->nLayers; Int *LayerBitRate = encParams->LayerBitRate; float *LayerFrameRate = encParams->LayerFrameRate; MultiPass **pMP = video->pMP; Int n, VBV_fullness; Int diff_counter; extern Bool SetProfile_BufferSize(VideoEncData *video, float delay, Int bInitialized); /* Reset video buffer size due to target bitrate change */ SetProfile_BufferSize(video, video->encParams->VBV_delay, 0); /* output: video->encParams->BufferSize[] */ for (n = 0; n < numLayers; n++) { /* Remaining stuff about frame dropping and underflow check in update RC */ updateRC_PostProc(rc[n], video); rc[n]->skip_next_frame = 0; /* must be initialized */ /* New changes: bitrate and framerate, Bs, max_BitVariance_num, TMN_TH(optional), encoded_frames(optional) */ rc[n]->Bs = video->encParams->BufferSize[n]; VBV_fullness = (Int)(rc[n]->Bs * 0.5); if (n == 0) { rc[n]->TMN_TH = (Int)((float)LayerBitRate[n] / LayerFrameRate[n]); rc[n]->bitrate = pMP[n]->bitrate = LayerBitRate[n]; rc[n]->framerate = pMP[n]->framerate = LayerFrameRate[n]; // For h263 or short header mode, the bit variation is within (-2*Rmax*1001/3000, 2*Rmax*1001/3000) if (video->encParams->H263_Enabled) { rc[n]->max_BitVariance_num = (Int)((rc[n]->Bs - video->encParams->maxFrameSize) / 2 / (rc[n]->bitrate / rc[n]->framerate / 10.0)) - 5; //rc[n]->max_BitVariance_num = (Int)((float)(rc[n]->Bs - rc[n]->VBV_fullness)/((float)LayerBitRate[n]/LayerFrameRate[n]/10.0))-5; } else // MPEG-4 normal modes { rc[n]->max_BitVariance_num = (Int)((float)(rc[n]->Bs - VBV_fullness) * 10 / ((float)LayerBitRate[n] / LayerFrameRate[n])) - 5; } } else { if (LayerFrameRate[n] - LayerFrameRate[n-1] > 0) /* 7/31/03 */ { rc[n]->TMN_TH = (Int)((float)(LayerBitRate[n] - LayerBitRate[n-1]) / (LayerFrameRate[n] - LayerFrameRate[n-1])); rc[n]->max_BitVariance_num = (Int)((float)(rc[n]->Bs - VBV_fullness) * 10 / ((float)rc[n]->TMN_TH)) - 5; if (rc[n]->max_BitVariance_num < 0) rc[n]->max_BitVariance_num += 5; } else /* 7/31/03 */ { rc[n]->TMN_TH = 1 << 30; rc[n]->max_BitVariance_num = 0; } rc[n]->bitrate = pMP[n]->bitrate = LayerBitRate[n] - LayerBitRate[n-1]; rc[n]->framerate = pMP[n]->framerate = LayerFrameRate[n] - LayerFrameRate[n-1]; } pMP[n]->target_bits_per_frame_prev = pMP[n]->target_bits_per_frame; pMP[n]->target_bits_per_frame = pMP[n]->bitrate / (float)(pMP[n]->framerate + 0.0001); /* 7/31/03 */ /* rc[n]->VBV_fullness and rc[n]->TMN_W should be kept same */ /* update pMP[n]->counter_BTdst and pMP[n]->counter_BTsrc */ diff_counter = (Int)((float)(rc[n]->VBV_fullness - rc[n]->TMN_W) / (pMP[n]->target_bits_per_frame / 10 + 0.0001)); /* 7/31/03 */ pMP[n]->counter_BTdst = pMP[n]->counter_BTsrc = 0; if (diff_counter > 0) pMP[n]->counter_BTdst = diff_counter; else if (diff_counter < 0) pMP[n]->counter_BTsrc = -diff_counter; rc[n]->TMN_W = (Int)(rc[n]->VBV_fullness - /* re-calculate rc[n]->TMN_W in order for higher accuracy */ (pMP[n]->target_bits_per_frame / 10) * (pMP[n]->counter_BTdst - pMP[n]->counter_BTsrc)); /* Keep the current average mad */ if (pMP[n]->aver_mad != 0) { pMP[n]->aver_mad_prev = pMP[n]->aver_mad; pMP[n]->encoded_frames_prev = pMP[n]->encoded_frames; } pMP[n]->aver_mad = 0; pMP[n]->overlapped_win_size = 4; /* Misc */ pMP[n]->sum_mad = pMP[n]->sum_QP = 0; //pMP[n]->encoded_frames_prev = pMP[n]->encoded_frames; pMP[n]->encoded_frames = pMP[n]->re_encoded_frames = pMP[n]->re_encoded_times = 0; } /* end of: for(n=0; n<numLayers; n++) */ return PV_SUCCESS; }