示例#1
0
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 ;
}
示例#3
0
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;

}