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

📄 encode.c

📁 avi2mpg1_src 中包含了mpeg1编码的源程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/*/************************************************************************/ void filter_subband(z,s)double z[HAN_SIZE], s[SBLIMIT];{   double y[64];   int i,j;   static char init = 0;   typedef double MM[SBLIMIT][64];   static MM *m;   long    SIZE_OF_MM;   SIZE_OF_MM      = SBLIMIT*64;   SIZE_OF_MM      *= 8;   if (!init)   {       m = (MM *) mem_alloc(SIZE_OF_MM, "filter");       create_ana_filter(*m);       init = 1;   }   for (i=0;i<64;i++)	   for (j=0, y[i] = 0;j<8;j++)		   y[i] += z[i+64*j];   for (i=0;i<SBLIMIT;i++)       for (j=0, s[i]= 0;j<64;j++)		   s[i] += (*m)[i][j] * y[j];}/************************************************************************//*/* encode_info()/*/* 功能:  将同步字节和头信息放入输出比特流/*/************************************************************************/ void encode_info(fr_ps,bs)frame_params *fr_ps;Bit_stream_struc *bs;{        layer *info = fr_ps->header;         putabits(bs,0xfff,12);                    /* syncword 12 bits */        put1bit(bs,info->version);               /* ID        1 bit  */        putabits(bs,4-info->lay,2);               /* layer     2 bits */        put1bit(bs,!info->error_protection);     /* bit set => no err prot */        putabits(bs,info->bitrate_index,4);        putabits(bs,info->sampling_frequency,2);        put1bit(bs,info->padding);        put1bit(bs,info->extension);             /* private_bit */        putabits(bs,info->mode,2);        putabits(bs,info->mode_ext,2);        put1bit(bs,info->copyright);        put1bit(bs,info->original);        putabits(bs,info->emphasis,2);} /************************************************************************//*/* mod()/*/* 功能: 返回变量的绝对值
/*/************************************************************************/ double mod(a)double a;{    return (a > 0) ? a : -a;} /************************************************************************//*/* I_combine_LR    (Layer I)/* II_combine_LR   (Layer II)/*/* 功能:将左右声道组合成一个单声道/*/* 结构描述:  左右子带采样的平均值放入#joint_sample#中。/*/*/************************************************************************/ void I_combine_LR(sb_sample, joint_sample)double sb_sample[2][3][SCALE_BLOCK][SBLIMIT];double joint_sample[3][SCALE_BLOCK][SBLIMIT];{       int sb, smp;    for(sb = 0; sb<SBLIMIT; ++sb)      for(smp = 0; smp<SCALE_BLOCK; ++smp)        joint_sample[0][smp][sb] = .5 *                    (sb_sample[0][0][smp][sb] + sb_sample[1][0][smp][sb]);} void II_combine_LR(sb_sample, joint_sample, sblimit)double sb_sample[2][3][SCALE_BLOCK][SBLIMIT];double joint_sample[3][SCALE_BLOCK][SBLIMIT];int sblimit;{     int sb, smp, sufr;    for(sb = 0; sb<sblimit; ++sb)      for(smp = 0; smp<SCALE_BLOCK; ++smp)         for(sufr = 0; sufr<3; ++sufr)            joint_sample[sufr][smp][sb] = .5 * (sb_sample[0][sufr][smp][sb]                                           + sb_sample[1][sufr][smp][sb]);} /************************************************************************/*/* I_scale_factor_calc     (Layer I)/* II_scale_factor_calc    (Layer II)/*/* 功能:算每个子带中每组12个子带采样的比例因子/*/* 结构解释:  从#multiple[]#选择比12个子带抽样值的绝对值的最大值还要大的
   做为比例因子,并将比例因子信息存入#scalar#中/*/* Layer II 有3组12子带采样/*/************************************************************************/ void I_scale_factor_calc(sb_sample,scalar,stereo)double sb_sample[][3][SCALE_BLOCK][SBLIMIT];unsigned int scalar[][3][SBLIMIT];int stereo;{   int i,j, k;   double s[SBLIMIT];    for (k=0;k<stereo;k++)   {     for (i=0;i<SBLIMIT;i++)       for (j=1, s[i] = mod(sb_sample[k][0][0][i]);j<SCALE_BLOCK;j++)         if (mod(sb_sample[k][0][j][i]) > s[i])            s[i] = mod(sb_sample[k][0][j][i]);      for (i=0;i<SBLIMIT;i++)       for (j=SCALE_RANGE-2,scalar[k][0][i]=0;j>=0;j--) /* $A 6/16/92 */         if (s[i] <= multiple[j])		 {            scalar[k][0][i] = j;            break;         }   }}/******************************** Layer II ******************************/ void II_scale_factor_calc(sb_sample,scalar,stereo,sblimit)double sb_sample[][3][SCALE_BLOCK][SBLIMIT];unsigned int scalar[][3][SBLIMIT];int stereo,sblimit;{  int i,j, k,t;  double s[SBLIMIT];   for (k=0;k<stereo;k++) for (t=0;t<3;t++)  {    for (i=0;i<sblimit;i++)      for (j=1, s[i] = mod(sb_sample[k][t][0][i]);j<SCALE_BLOCK;j++)        if (mod(sb_sample[k][t][j][i]) > s[i])             s[i] = mod(sb_sample[k][t][j][i]);     for (i=0;i<sblimit;i++)       for (j=SCALE_RANGE-2,scalar[k][t][i]=0;j>=0;j--)    /* $A 6/16/92 */         if (s[i] <= multiple[j])		 {            scalar[k][t][i] = j;            break;		 }      for (i=sblimit;i<SBLIMIT;i++) scalar[k][t][i] = SCALE_RANGE-1;  }}/************************************************************************/*/* pick_scale  (Layer II)/*/* 功能: 对每个子带,将3各比例因子中最小的和一个帧放入#max_sc#.  /* 这用于心理声学模型I./*/************************************************************************/ void pick_scale(scalar, fr_ps, max_sc)unsigned int scalar[2][3][SBLIMIT];frame_params *fr_ps;double max_sc[2][SBLIMIT];{  int i,j,k;  unsigned int max;  int stereo  = fr_ps->stereo;  int sblimit = fr_ps->sblimit;   for (k=0;k<stereo;k++)    for (i=0;i<sblimit;max_sc[k][i] = multiple[max],i++)      for (j=1, max = scalar[k][0][i];j<3;j++)         if (max > scalar[k][j][i])			 max = scalar[k][j][i];  for (i=sblimit;i<SBLIMIT;i++)	  max_sc[0][i] = max_sc[1][i] = 1E-20;}/************************************************************************/*/* put_scale   (Layer I)/*/* 功能: 将#max_sc#设置为#scalar中的比例因子索引./*/************************************************************************/ void put_scale(scalar, fr_ps, max_sc)unsigned int scalar[2][3][SBLIMIT];frame_params *fr_ps;double max_sc[2][SBLIMIT];{   int i,k;   int stereo  = fr_ps->stereo;   int sblimit = fr_ps->sblimit;    for (k=0;k<stereo;k++) for (i=0;i<SBLIMIT;i++)        max_sc[k][i] = multiple[scalar[k][0][i]];} /************************************************************************/*/* II_transmission_pattern (Layer II only)/*/* 功能:对给定的子带传送1个或2个或全部3个比例因子并填充相应的比例因子选择
        信息/*/* 结构描述:  子带和信道根据三个比例因子的变化划分。如果三个比例因子变化
      不大,则仅传送1个或2个比例因子。/*/************************************************************************/ void II_transmission_pattern(scalar, scfsi, fr_ps)unsigned int scalar[2][3][SBLIMIT];unsigned int scfsi[2][SBLIMIT];frame_params *fr_ps;{   int stereo  = fr_ps->stereo;   int sblimit = fr_ps->sblimit;   int dscf[2];   int sclass[2],i,j,k;   static int pattern[5][5] = {0x123, 0x122, 0x122, 0x133, 0x123,                               0x113, 0x111, 0x111, 0x444, 0x113,                               0x111, 0x111, 0x111, 0x333, 0x113,                               0x222, 0x222, 0x222, 0x333, 0x123,                               0x123, 0x122, 0x122, 0x133, 0x123};    for (k=0;k<stereo;k++)     for (i=0;i<sblimit;i++)	 {       dscf[0] =  (scalar[k][0][i]-scalar[k][1][i]);       dscf[1] =  (scalar[k][1][i]-scalar[k][2][i]);       for (j=0;j<2;j++)	   {         if (dscf[j]<=-3)			 sclass[j] = 0;         else if (dscf[j] > -3 && dscf[j] <0)			 sclass[j] = 1;              else if (dscf[j] == 0)				  sclass[j] = 2;                   else if (dscf[j] > 0 && dscf[j] < 3)					   sclass[j] = 3;                        else sclass[j] = 4;       }       switch (pattern[sclass[0]][sclass[1]])	   {         case 0x123 :			 scfsi[k][i] = 0;             break;         case 0x122 :			 scfsi[k][i] = 3;             scalar[k][2][i] = scalar[k][1][i];             break;         case 0x133 :			 scfsi[k][i] = 3;             scalar[k][1][i] = scalar[k][2][i];             break;         case 0x113 :			 scfsi[k][i] = 1;             scalar[k][1][i] = scalar[k][0][i];             break;         case 0x111 :			 scfsi[k][i] = 2;             scalar[k][1][i] = scalar[k][2][i] = scalar[k][0][i];             break;         case 0x222 :			 scfsi[k][i] = 2;             scalar[k][0][i] = scalar[k][2][i] = scalar[k][1][i];             break;         case 0x333 :			 scfsi[k][i] = 2;             scalar[k][0][i] = scalar[k][1][i] = scalar[k][2][i];             break;         case 0x444 :			 scfsi[k][i] = 2;             if (scalar[k][0][i] > scalar[k][2][i])                 scalar[k][0][i] = scalar[k][2][i];             scalar[k][1][i] = scalar[k][2][i] = scalar[k][0][i];	   }	 }} /************************************************************************/*/* I_encode_scale  (Layer I)/* II_encode_scale (Layer II)/*/* 功能: 编码后的比例因子信息放入输出队列等待传送/*/************************************************************************/ void I_encode_scale(scalar, bit_alloc, fr_ps, bs)unsigned int scalar[2][3][SBLIMIT];unsigned int bit_alloc[2][SBLIMIT];frame_params *fr_ps;Bit_stream_struc *bs;{   int stereo  = fr_ps->stereo;   int sblimit = fr_ps->sblimit;   int i,j;    for (i=0;i<SBLIMIT;i++)	   for (j=0;j<stereo;j++)           if (bit_alloc[j][i])			   putabits(bs,scalar[j][0][i],6);} /***************************** Layer II  ********************************/ void II_encode_scale(bit_alloc, scfsi, scalar, fr_ps, bs)unsigned int bit_alloc[2][SBLIMIT], scfsi[2][SBLIMIT];unsigned int scalar[2][3][SBLIMIT];frame_params *fr_ps;Bit_stream_struc *bs;{   int stereo  = fr_ps->stereo;   int sblimit = fr_ps->sblimit;   int jsbound = fr_ps->jsbound;   int i,j,k;    for (i=0;i<sblimit;i++)	   for (k=0;k<stereo;k++)           if (bit_alloc[k][i])			   putabits(bs,scfsi[k][i],2);    for (i=0;i<sblimit;i++)	   for (k=0;k<stereo;k++)           if (bit_alloc[k][i])          switch (scfsi[k][i]) {           case 0: for (j=0;j<3;j++)                     putabits(bs,scalar[k][j][i],6);                   break;           case 1:           case 3: putabits(bs,scalar[k][0][i],6);                   putabits(bs,scalar[k][2][i],6);                   break;           case 2: putabits(bs,scalar[k][0][i],6);        }} /*=======================================================================\|      下面的程序是在心理声学模型已经计算出掩蔽阈值后进行的              ||                                                                        |\=======================================================================*/ /************************************************************************/*/* I_bits_for_nonoise  (Layer I)/* II_bits_for_nonoise (Layer II)/*/* 功能:用计算出的掩蔽噪声比可以计算出分配给子带信号的量化位数/*/* 结构描述:/* bbal = # 用来为比特分配进行编码所需的bits /* bsel = # 用来为比例因子选择信息进行编码所需的bits/* banc = # 用来为辅助信息进行编码所需的bits/*/* 对每个子带和信道,我们累加bit的值直到出现以下情况:
/* -达到该信道能允许分配的最大bit位数
/* -掩蔽噪声比(MNR)好于或等于最小掩蔽水平
/*/* 支持联合立体声/*/************************************************************************/static double snr[18] = {0.00, 7.00, 11.00, 16.00, 20.84,                         25.28, 31.59, 37.75, 43.84,                         49.89, 55.93, 61.96, 67.98, 74.01,                         80.03, 86.05, 92.01, 98.01};int I_bits_for_nonoise(perm_smr, fr_ps)double perm_smr[2][SBLIMIT];frame_params *fr_ps;{   int i,j,k;   int stereo  = fr_ps->stereo;   int sblimit = fr_ps->sblimit;   int jsbound = fr_ps->jsbound;   int req_bits = 0;       req_bits = 32 + 4 * ( (jsbound * stereo) + (SBLIMIT-jsbound) );    for(i=0; i<SBLIMIT; ++i)     for(j=0; j<((i<jsbound)?stereo:1); ++j) {       for(k=0;k<14; ++k)         if( (-perm_smr[j][i] + snr[k]) >= NOISY_MIN_MNR)           break; /* 已找到足够的bit了 */         if(stereo == 2 && i >= jsbound)                for(;k<14; ++k)             if( (-perm_smr[1-j][i] + snr[k]) >= NOISY_MIN_MNR) break;         if(k>0) req_bits += (k+1)*SCALE_BLOCK + 6*((i>=jsbound)?stereo:1);   }   return req_bits;} /***************************** Layer II  ********************************/ int II_bits_for_nonoise(perm_smr, scfsi, fr_ps)double perm_smr[2][SBLIMIT];unsigned int scfsi[2][SBLIMIT];frame_params *fr_ps;{   int sb,ch,ba;   int stereo  = fr_ps->stereo;   int sblimit = fr_ps->sblimit;   int jsbound = fr_ps->jsbound;   al_table *alloc = fr_ps->alloc;   int req_bits = 0, bbal = 0, berr = 0, banc = 32;   int maxAlloc, sel_bits, sc_bits, smp_bits;static int sfsPerScfsi[] = { 3,2,1,2 };       /* added 92-08-11 shn */   if (fr_ps->header->error_protection) berr=16; else berr=0;     for (sb=0; sb<jsbound; ++sb)     bbal += stereo * (*alloc)[sb][0].bits;   for (sb=jsbound; sb<sblimit; ++sb)     bbal += (*alloc)[sb][0].bits;   req_bits = banc + bbal + berr;    for(sb=0; sb<sblimit; ++sb)     for(ch=0; ch<((sb<jsbound)?stereo:1); ++ch) {       maxAlloc = (1<<(*alloc)[sb][0].bits)-1;       sel_bits = sc_bits = smp_bits = 0;       for(ba=0;ba<maxAlloc-1; ++ba)         if( (-perm_smr[ch][sb] + snr[(*alloc)[sb][ba].quant+((ba>0)?1:0)])             >= NOISY_MIN_MNR)            break;      /* we found enough bits */       if(stereo == 2 && sb >= jsbound) /* check other JS channel */         for(;ba<maxAlloc-1; ++ba)           if( (-perm_smr[1-ch][sb]+ snr[(*alloc)[sb][ba].quant+((ba>0)?1:0)])               >= NOISY_MIN_MNR)             break;       if(ba>0) {         smp_bits = SCALE_BLOCK * ((*alloc)[sb][ba].group * (*alloc)[sb][ba].bits);         /* scale factor bits required for subband */         sel_bits = 2;         sc_bits  = 6 * sfsPerScfsi[scfsi[ch][sb]];         if(stereo == 2 && sb >= jsbound) {           /* each new js sb has L+R scfsis */           sel_bits += 2;           sc_bits  += 6 * sfsPerScfsi[scfsi[1-ch][sb]];         }         req_bits += smp_bits+sel_bits+sc_bits;       }   }   return req_bits;} /************************************************************************/*/* I_main_bit_allocation   (Layer I)/* II_main_bit_allocation  (Layer II)/*/* 功能: 对联合立体声模式,决定使用4中联合立体声中的哪种。然后调用 *_a_bit_allocation()
/* 它将为每个子带分配比特,知道比特用完和MNR达到阈值/*/*/************************************************************************/ void I_main_bit_allocation(perm_smr, bit_alloc, adb, fr_ps)double perm_smr[2][SBLIMIT];unsigned int bit_alloc[2][SBLIMIT];int *adb;frame_params *fr_ps;{   int  noisy_sbs;   int  mode, mode_ext, lay, i;   int  rq_db, av_db = *adb;static  int init = 0;    if(init == 0) {     /* rearrange snr for layer I */     snr[2] = snr[3];     for (i=3;i<16;i++) snr[i] = snr[i+2];     init = 1;   }    if((mode = fr_ps->actual_mode) == MPG_MD_JOINT_STEREO) {     fr_ps->header->mode = MPG_MD_STEREO;     fr_ps->header->mode_ext = 0;     fr_ps->jsbound = fr_ps->sblimit;     if(rq_db = I_bits_for_nonoise(perm_smr, fr_ps) > *adb) {       fr_ps->header->mode = MPG_MD_JOINT_STEREO;

⌨️ 快捷键说明

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