⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 backpred.c

📁 mpeg4 video codec mpeg4 video codec
💻 C
字号:
/**********************************************************************This software module was originally developed byand edited by Nokia in the course ofdevelopment of the MPEG-2 NBC/MPEG-4 Audio standardISO/IEC 13818-7, 14496-1,2 and 3. This software module is animplementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio toolsas specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC givesusers of the MPEG-2 NBC/MPEG-4 Audio standards free license to thissoftware module or modifications thereof for use in hardware orsoftware products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audiostandards. Those intending to use this software module in hardware orsoftware products are advised that this use may infringe existingpatents. The original developer of this software module and his/hercompany, the subsequent editors and their companies, and ISO/IEC haveno liability for use of this software module or modifications thereofin an implementation. Copyright is not released for non MPEG-2NBC/MPEG-4 Audio conforming products. The original developer retainsfull right to use the code for his/her own purpose, assign or donatethe code to a third party and to inhibit third party from using thecode for non MPEG-2 NBC/MPEG-4 Audio conforming products. Thiscopyright notice must be included in all copies or derivative works.Copyright (c) 1997.**********************************************************************//* * $Id: backpred.c,v 1.1 2006/02/23 14:30:26 kevin-fu Exp $ */#include <math.h>#include "frame.h"#include "coder.h"#include "channels.h"#include "backpred.h"void PredInit(faacEncHandle hEncoder){    unsigned int channel;    for (channel = 0; channel < hEncoder->numChannels; channel++) {        BwpInfo *bwpInfo = &(hEncoder->coderInfo[channel].bwpInfo);        bwpInfo->psy_init_mc = 0;        bwpInfo->reset_count_mc = 0;    }}void PredCalcPrediction(double *act_spec, double *last_spec, int btype,                        int nsfb,                        int *isfb_width,                        CoderInfo *coderInfo,                        ChannelInfo *channelInfo,                        int chanNum){    int i, k, j, cb_long;    int leftChanNum;    int isRightWithCommonWindow;    double num_bit, snr[SBMAX_L];    double energy[BLOCK_LEN_LONG], snr_p[BLOCK_LEN_LONG], temp1, temp2;    ChannelInfo *thisChannel;    /* Set pointers for specified channel number */    /* int psy_init; */    int *psy_init;    double (*dr)[BLOCK_LEN_LONG],(*e)[BLOCK_LEN_LONG];    double (*K)[BLOCK_LEN_LONG], (*R)[BLOCK_LEN_LONG];    double (*VAR)[BLOCK_LEN_LONG], (*KOR)[BLOCK_LEN_LONG];    double *sb_samples_pred;    int *thisLineNeedsResetting;    /* int reset_count; */    int *reset_count;    int *pred_global_flag;    int *pred_sfb_flag;    int *reset_group;    /* Set pointers for this chanNum */    pred_global_flag = &(coderInfo[chanNum].pred_global_flag);    pred_sfb_flag = coderInfo[chanNum].pred_sfb_flag;    reset_group = &(coderInfo[chanNum].reset_group_number);    psy_init = &coderInfo[chanNum].bwpInfo.psy_init_mc;    dr = &coderInfo[chanNum].bwpInfo.dr_mc[0];    e = &coderInfo[chanNum].bwpInfo.e_mc[0];    K = &coderInfo[chanNum].bwpInfo.K_mc[0];    R = &coderInfo[chanNum].bwpInfo.R_mc[0];    VAR = &coderInfo[chanNum].bwpInfo.VAR_mc[0];    KOR = &coderInfo[chanNum].bwpInfo.KOR_mc[0];    sb_samples_pred = &coderInfo[chanNum].bwpInfo.sb_samples_pred_mc[0];    thisLineNeedsResetting = &coderInfo[chanNum].bwpInfo.thisLineNeedsResetting_mc[0];    reset_count = &coderInfo[chanNum].bwpInfo.reset_count_mc;    thisChannel = &(channelInfo[chanNum]);    *psy_init = (*psy_init && (btype!=2));    if((*psy_init) == 0) {        for (j=0; j<BLOCK_LEN_LONG; j++) {            thisLineNeedsResetting[j]=1;        }        *psy_init = 1;    }    if (btype==2) {        pred_global_flag[0]=0;        /* SHORT WINDOWS reset all the co-efficients    */        if (thisChannel->ch_is_left) {            (*reset_count)++;            if (*reset_count >= 31 * RESET_FRAME)                *reset_count = RESET_FRAME;        }        return;    }    /**************************************************/    /*  Compute state using last_spec                 */    /**************************************************/    for (i=0;i<BLOCK_LEN_LONG;i++)    {        /* e[0][i]=last_spec[i]; */        e[0][i]=last_spec[i]+sb_samples_pred[i];        for(j=1;j<=LPC;j++)            e[j][i] = e[j-1][i]-K[j][i]*R[j-1][i];        for(j=1;j<LPC;j++)            dr[j][i] = K[j][i]*e[j-1][i];        for(j=1;j<=LPC;j++) {            VAR[j][i] = ALPHA*VAR[j][i]+.5*(R[j-1][i]*R[j-1][i]+e[j-1][i]*e[j-1][i]);            KOR[j][i] = ALPHA*KOR[j][i]+R[j-1][i]*e[j-1][i];        }        for(j=LPC-1;j>=1;j--)            R[j][i] = A*(R[j-1][i]-dr[j][i]);        R[0][i] = A*e[0][i];    }    /**************************************************/    /* Reset state here if resets were sent           */    /**************************************************/    for (i=0;i<BLOCK_LEN_LONG;i++) {        if (thisLineNeedsResetting[i]) {            for (j = 0; j <= LPC; j++)            {                K[j][i] = 0.0;                e[j][i] = 0.0;                R[j][i] = 0.0;                VAR[j][i] = 1.0;                KOR[j][i] = 0.0;                dr[j][i] = 0.0;            }        }    }    /**************************************************/    /* Compute predictor coefficients, predicted data */    /**************************************************/    for (i=0;i<BLOCK_LEN_LONG;i++)    {        for(j=1;j<=LPC;j++) {            if(VAR[j][i]>MINVAR)                K[j][i] = KOR[j][i]/VAR[j][i]*B;            else                K[j][i] = 0;        }    }    for (k=0; k<BLOCK_LEN_LONG; k++)    {        sb_samples_pred[k]=0.0;        for (i=1; i<=LPC; i++)            sb_samples_pred[k]+=K[i][k]*R[i-1][k];    }    /***********************************************************/    /* If this is the right channel of a channel_pair_element, */    /* AND common_window is 1 in this channel_pair_element,    */    /* THEN copy predictor data to use from the left channel.  */    /* ELSE determine independent predictor data and resets.   */    /***********************************************************/    /* BE CAREFUL HERE, this assumes that predictor data has   */    /* already been determined for the left channel!!          */    /***********************************************************/    isRightWithCommonWindow = 0;     /* Is this a right channel with common_window?*/    if ((thisChannel->cpe)&&( !(thisChannel->ch_is_left))) {        leftChanNum = thisChannel->paired_ch;        if (channelInfo[leftChanNum].common_window) {            isRightWithCommonWindow = 1;        }    }    if (isRightWithCommonWindow) {        /**************************************************/        /* Use predictor data from the left channel.      */        /**************************************************/        CopyPredInfo(&(coderInfo[chanNum]),&(coderInfo[leftChanNum]));        /* Make sure to turn off bands with intensity stereo */#if 0        if (thisChannel->is_info.is_present) {            for (i=0; i<nsfb; i++) {                if (thisChannel->is_info.is_used[i]) {                    pred_sfb_flag[i] = 0;                }            }        }#endif        cb_long=0;        for (i=0; i<nsfb; i++)        {            if (!pred_sfb_flag[i]) {                for (j=cb_long; j<cb_long+isfb_width[i]; j++)                    sb_samples_pred[j]=0.0;            }            cb_long+=isfb_width[i];        }        /* Disable prediction for bands nsfb through SBMAX_L */        for (i=j;i<BLOCK_LEN_LONG;i++) {            sb_samples_pred[i]=0.0;        }        for (i=nsfb;i<SBMAX_L;i++) {            pred_sfb_flag[i]=0;        }        /* Is global enable set, if not enabled predicted samples are zeroed */        if(!pred_global_flag[0]) {            for (j=0; j<BLOCK_LEN_LONG; j++)                sb_samples_pred[j]=0.0;        }        for (j=0; j<BLOCK_LEN_LONG; j++)            act_spec[j]-=sb_samples_pred[j];    } else {        /**************************************************/        /* Determine whether to enable/disable prediction */        /**************************************************/        for (k=0; k<BLOCK_LEN_LONG; k++) {            energy[k]=act_spec[k]*act_spec[k];            snr_p[k]=(act_spec[k]-sb_samples_pred[k])*(act_spec[k]-sb_samples_pred[k]);        }        cb_long=0;        for (i=0; i<nsfb; i++) {            pred_sfb_flag[i]=1;            temp1=0.0;            temp2=0.0;            for (j=cb_long; j<cb_long+isfb_width[i]; j++) {                temp1+=energy[j];                temp2+=snr_p[j];            }            if(temp2<1.e-20)                temp2=1.e-20;            if(temp1!=0.0)                snr[i]=-10.*log10((double ) temp2/temp1);            else                snr[i]=0.0;            if(snr[i]<=0.0) {                pred_sfb_flag[i]=0;                for (j=cb_long; j<cb_long+isfb_width[i]; j++)                    sb_samples_pred[j]=0.0;            }            cb_long+=isfb_width[i];        }        /* Disable prediction for bands nsfb through SBMAX_L */        for (i=j;i<BLOCK_LEN_LONG;i++) {            sb_samples_pred[i]=0.0;        }        for (i=nsfb;i<SBMAX_L;i++) {            pred_sfb_flag[i]=0;        }        num_bit=0.0;        for (i=0; i<nsfb; i++)            if(snr[i]>0.0)                num_bit+=snr[i]/6.*isfb_width[i];        /* Determine global enable, if not enabled predicted samples are zeroed */        pred_global_flag[0]=1;        if(num_bit<50) {            pred_global_flag[0]=0; num_bit=0.0;            for (j=0; j<BLOCK_LEN_LONG; j++)                sb_samples_pred[j]=0.0;        }        for (j=0; j<BLOCK_LEN_LONG; j++)            act_spec[j]-=sb_samples_pred[j];    }    /**********************************************************/    /* If this is a left channel, determine pred resets.      */    /* If this is a right channel, using pred reset data from */    /* left channel.  Keep left and right resets in sync.     */    /**********************************************************/    if ((thisChannel->cpe)&&( !(thisChannel->ch_is_left))) {        /*  if (!thisChannel->ch_is_left) {*/        /**********************************************************/        /* Using predictor reset data from the left channel.      */        /**********************************************************/        reset_count = &coderInfo[leftChanNum].bwpInfo.reset_count_mc;        /* Reset the frame counter */        for (i=0;i<BLOCK_LEN_LONG;i++) {            thisLineNeedsResetting[i]=0;        }        reset_group = &(coderInfo[chanNum].reset_group_number);        if (*reset_count % RESET_FRAME == 0)        { /* Send a reset in this frame */            *reset_group = *reset_count / 8;            for (i = *reset_group - 1; i < BLOCK_LEN_LONG; i += 30)            {                thisLineNeedsResetting[i]=1;            }        }        else            *reset_group = -1;    } else {        /******************************************************************/        /* Determine whether a prediction reset is required - if so, then */        /* set reset flag for the appropriate group.                      */        /******************************************************************/        /* Increase counter on left channel, keep left and right resets in sync */        (*reset_count)++;        /* Reset the frame counter */        for (i=0;i<BLOCK_LEN_LONG;i++) {            thisLineNeedsResetting[i]=0;        }        if (*reset_count >= 31 * RESET_FRAME)            *reset_count = RESET_FRAME;        if (*reset_count % RESET_FRAME == 0)        { /* Send a reset in this frame */            *reset_group = *reset_count / 8;            for (i = *reset_group - 1; i < BLOCK_LEN_LONG; i += 30)            {                thisLineNeedsResetting[i]=1;            }        }        else            *reset_group = -1;    }    /* Ensure that prediction data is sent when there is a prediction    * reset.    */    if (*reset_group != -1 && pred_global_flag[0] == 0)    {        pred_global_flag[0] = 1;        for (i = 0; i < nsfb; i++)            pred_sfb_flag[i] = 0;    }}void CopyPredInfo(CoderInfo *right, CoderInfo *left){    int band;    right->pred_global_flag = left->pred_global_flag;    right->reset_group_number = left->reset_group_number;    for (band = 0; band<MAX_SCFAC_BANDS; band++) {        right->pred_sfb_flag[band] = left->pred_sfb_flag[band];    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -