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

📄 taudiofilter.cpp

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 CPP
📖 第 1 页 / 共 2 页
字号:
     if (c_loop)
      fc_3dnow(inbuf,samples,(unsigned int)c_loop);
    }
   #endif
   else if (fc_sse && Tconfig::cpu_flags&FF_CPU_SSE) //TODO fix?
    {
     c_miss=count&3;
     c_loop=count-c_miss;
     if (c_loop)
      fc_sse(inbuf,samples,(unsigned int)c_loop);
    }
   else
    {
     c_miss=count;
     c_loop=0;
    }
   for (size_t i=0;i<c_miss;i++)
    samples[i+c_loop]=TsampleFormatInfo<Tout>::limit(inbuf[i+c_loop]*TsampleFormatInfo<Tout>::max());
   return samples;
  }
};

//---------------------------- int16 -> float ----------------------------
#ifndef WIN64
 extern "C" void convert_16_float_3dnow(const int16_t*inbuf,float *samples,unsigned int c_loop);
#else
 #define convert_16_float_3dnow NULL
#endif
static void convert_16_float_sse(const int16_t*inbuf,float *samples,unsigned int c_loop)
{
 int eax=0;
 int edx=c_loop;
 const unsigned char *esi=(const unsigned char*)inbuf;
 edx<<=1;// Number of input bytes.
 const __m128 divisor_float_16=_mm_set_ps1(0.000030517578125f);
 __m128 xmm7=divisor_float_16;
 for (unsigned char *edi=(unsigned char*)samples;eax!=edx;eax+=8)
  {
   __m64 mm0,mm1;
   movq      (mm1, esi+eax);            //;  d c | b a
   punpcklwd (mm0, mm1  );                //;  b x | a x
   punpckhwd (mm1, mm1  );                //;  d d | c c
   psrad     (mm0, 16   );                //;  sign extend
   psrad     (mm1, 16   );                //;  sign extend
   __m128 xmm0,xmm1;
   cvtpi2ps  (xmm0, mm0 );                //;  - b | - a -> float
   cvtpi2ps  (xmm1, mm1 );                //;  - d | - c -> float
   movlhps   (xmm0, xmm1);                //;  xd  xc || xb  xa
   mulps     (xmm0, xmm7);                //;  *=1/MAX_SHORT
   movups    (edi+(eax+8)*2-16, xmm0);      //;  store xd | xc | xb | xa
  }
 _mm_empty();
}
#ifdef __SSE2__
static void convert_16_float_sse2(const int16_t*inbuf,float *samples,unsigned int c_loop)
{
 int eax=0;
 int edx=c_loop;
 const unsigned char *esi=(const unsigned char*)inbuf;
 edx<<= 1;  // Number of input bytes.
 __m128 xmm7=_mm_set_ps1(0.000030517578125f);
 for (unsigned char *edi=(unsigned char*)samples;eax!=edx;eax+=16)
  {
   __m128i xmm0,xmm1;
   movdqu    (xmm1, esi+eax);           //  h g | f e | d c | b a

   punpcklwd (xmm0, xmm1);                //  d x | c x | b x | a x
   punpckhwd (xmm1, xmm1);                //  h h | g g | f f | e e
   psrad     (xmm0, 16 );                 //  sign extend
   psrad     (xmm1, 16 );                 //  sign extend
   __m128 xmm2,xmm3;
   cvtdq2ps  (xmm2, xmm0);                //  - d | - c | - b | - a -> float
   cvtdq2ps  (xmm3, xmm1);                //  - h | - g | - f | - e -> float
   mulps     (xmm2, xmm7);                //  *=1/MAX_SHORT
   mulps     (xmm3, xmm7);                //  *=1/MAX_SHORT
   movaps    (edi+(eax+16)*2-32, xmm2);      //  store xd | xc | xb | xa
   movaps    (edi+(eax+16)*2-16, xmm3);      //  store xh | xg | xf | xe
  }
}
#else
 #define convert_16_float_sse2 NULL
#endif

//---------------------------- int32 -> float ----------------------------
#ifndef WIN64
 extern "C" void convert_32_float_3dnow(const int32_t*inbuf,float *samples,unsigned int c_loop);
#else
 #define convert_32_float_3dnow NULL
#endif
static void convert_32_float_sse(const int32_t*inbuf,float *samples,unsigned int c_loop)
{
 int eax=0;
 int edx= c_loop;
 const unsigned char *esi=(const unsigned char*)inbuf;
 edx<<=2;//  in input bytes (*4)
 const __m128 divisor_float_32=_mm_set_ps1(4.656612875245796924105750827168e-10f);
 __m128 xmm7=divisor_float_32;
 for (unsigned char *edi=(unsigned char*)samples;eax!=edx;eax+= 16)
  {
   __m64 mm0,mm1;
   movq     (mm0, esi+eax);        // b b | a a
   movq     (mm1, esi+eax+8);      // d d | c c
   __m128 xmm0,xmm1;
   cvtpi2ps (xmm0, mm0);             // b b | a a -> float
   cvtpi2ps (xmm1, mm1);             // d d | c c -> float
   movlhps  (xmm0, xmm1);            // xd  xc || xb  xa
   mulps    (xmm0, xmm7);            // *=1/MAX_INT
   movups   (edi+eax-16+16, xmm0);    // store xd | xc | xb | xa
  }
 _mm_empty();
}
#ifdef __SSE2__
static void convert_32_float_sse2(const int32_t*inbuf,float *samples,unsigned int c_loop)
{
 int eax=0;                 //  count
 int edx= c_loop;
 const unsigned char *esi=(const unsigned char*)inbuf;
 edx<<= 2;                     //  in input bytes (*4)
 __m128 xmm7=_mm_set_ps1(4.656612875245796924105750827168e-10f);
 for (unsigned char *edi=(unsigned char*)samples;eax!= edx;eax+=32)
  {
   __m128i xmm0,xmm1;
   movdqu   (xmm0, esi+eax);        //  dd | cc | bb | aa
   movdqu   (xmm1, esi+eax+16);     //  hh | gg | ff | ee
   __m128 xmm2,xmm3;
   cvtdq2ps (xmm2, xmm0);             //  xd | xc | xb | xa
   cvtdq2ps (xmm3, xmm1);             //  xh | xg | xf | xe
   mulps    (xmm2, xmm7);             //  *=1/MAX_INT
   mulps    (xmm3, xmm7);             //  *=1/MAX_INT
   movaps   (edi+eax+32-32, xmm2);     //  store xd | xc | xb | xa
   movaps   (edi+eax+32-16, xmm3);     //  store xh | xg | xf | xe
  }
}
#else
 #define convert_32_float_sse2 NULL
#endif

template<class Tin> struct TconvertToFloat
{
 typedef void (*TconvertToFloatFc)(const Tin*inbuf,float *samples,unsigned int c_loop);
 static float* convert(const Tin *samples,float *outbuf,size_t count,TconvertToFloatFc fc_3dnow,TconvertToFloatFc fc_sse,TconvertToFloatFc fc_sse2)
  {
   static const float divisor=1.0f/-TsampleFormatInfo<Tin>::min();
   size_t c_miss,c_loop;
   if (fc_sse2 && Tconfig::cpu_flags&FF_CPU_SSE2)
    {
     while (((intptr_t)outbuf&15) && count)
      {
       *outbuf++=divisor*(float)*samples++;
       count-=1;
      }
     c_miss=count&7;
     c_loop=count-c_miss;
     if (c_loop)
      fc_sse2(samples,outbuf,(unsigned int)c_loop);
    }
   #ifndef WIN64
   else if (fc_3dnow && Tconfig::cpu_flags&FF_CPU_3DNOW)
    {
     c_miss=count&3;
     c_loop=count-c_miss;
     if (c_loop)
      fc_3dnow(samples,outbuf,(unsigned int)c_loop);
    }
   #endif
   else if (fc_sse && Tconfig::cpu_flags&FF_CPU_SSE)
    {
     c_miss=count&3;
     c_loop=count-c_miss;
     if (c_loop)
      fc_sse(samples,outbuf,(unsigned int)c_loop);
    }
   else
    {
     c_miss=count;
     c_loop=0;
    }
   for (size_t i=0;i<c_miss;i++)
    outbuf[i+c_loop]=(float)samples[i+c_loop]*divisor;
   return outbuf;
  }
};

void* TaudioFilter::convertTo(const TsampleFormat &sfIn,const void *bufIn,size_t numsamples,const TsampleFormat &sfOut,size_t samplestoalloc)
{
 if (sfIn.sf==sfOut.sf || numsamples==0) return (void*)bufIn;
 void *bufOut=alloc_buffer(sfOut,samplestoalloc?samplestoalloc:numsamples);
 const size_t count=sfIn.nchannels*numsamples;
 switch (sfIn.sf)
  {
   case TsampleFormat::SF_FLOAT32:
    {
     int dithering=deci->getParam2(IDFF_dithering),noiseshaping=deci->getParam2(IDFF_noiseShaping); //TODO don't read this always
     if (dithering || noiseshaping)
      {
       if (!dither || oldnoiseshaping!=noiseshaping || oldsfout!=sfOut.sf)
        {
         oldnoiseshaping=noiseshaping;oldsfout=sfOut.sf;
         if (dither) delete dither;
         dither=new Tdither(sfOut.bitsPerSample(),noiseshaping);
        }
       switch (sfOut.sf)
        {
         case TsampleFormat::SF_PCM16:return dither->process((const float*)bufIn,(int16_t*)bufOut,sfOut.nchannels,numsamples,dithering);
         case TsampleFormat::SF_PCM24:return dither->process((const float*)bufIn,(int24_t*)bufOut,sfOut.nchannels,numsamples,dithering);
         case TsampleFormat::SF_PCM32:return dither->process((const float*)bufIn,(int32_t*)bufOut,sfOut.nchannels,numsamples,dithering);
        }
      }
     else
      switch (sfOut.sf)
       {
        case TsampleFormat::SF_PCM16:return TconvertFromFloat<int16_t>::convert((const float*)bufIn,(int16_t*)bufOut,count,convert_float_16_3dnow,convert_float_16_sse,convert_float_16_sse2);
        case TsampleFormat::SF_PCM24:return TconvertFromFloat<int24_t>::convert((const float*)bufIn,(int24_t*)bufOut,count,NULL,NULL,NULL);
        case TsampleFormat::SF_PCM32:return TconvertFromFloat<int32_t>::convert((const float*)bufIn,(int32_t*)bufOut,count,convert_float_32_3dnow,convert_float_32_sse,convert_float_32_sse2);
       }
     break;
    }
   case TsampleFormat::SF_PCM16:
    switch (sfOut.sf)
     {
      case TsampleFormat::SF_PCM24:return convert((const int16_t*)bufIn,(int24_t*)bufOut,count);
      case TsampleFormat::SF_PCM32:return convert((const int16_t*)bufIn,(int32_t*)bufOut,count);
      case TsampleFormat::SF_FLOAT32:return TconvertToFloat<int16_t>::convert((const int16_t*)bufIn,(float*)bufOut,count,convert_16_float_3dnow,convert_16_float_sse,convert_16_float_sse2);
     }
    break;
   case TsampleFormat::SF_PCM24:
    switch (sfOut.sf)
     {
      case TsampleFormat::SF_PCM16:return convert((const int24_t*)bufIn,(int16_t*)bufOut,count);
      case TsampleFormat::SF_PCM32:return convert((const int24_t*)bufIn,(int32_t*)bufOut,count);
      case TsampleFormat::SF_FLOAT32:return TconvertToFloat<int24_t>::convert((const int24_t*)bufIn,(float*)bufOut,count,NULL,NULL,NULL);
     }
    break;
   case TsampleFormat::SF_PCM32:
    switch (sfOut.sf)
     {
      case TsampleFormat::SF_PCM16:return convert((const int32_t*)bufIn,(int16_t*)bufOut,count);
      case TsampleFormat::SF_PCM24:return convert((const int32_t*)bufIn,(int24_t*)bufOut,count);
      case TsampleFormat::SF_FLOAT32:return TconvertToFloat<int32_t>::convert((const int32_t*)bufIn,(float*)bufOut,count,convert_32_float_3dnow,convert_32_float_sse,convert_32_float_sse2);
     }
    break;
  }
 return bufOut;
}

void* TaudioFilter::init(const TfilterSettingsAudio *cfg,TsampleFormat &sf,const void *bufIn,size_t numsamples,size_t samplestoalloc)
{
 bool honourPreferred=true;
 int supSF=getSupportedFormats(cfg,&honourPreferred);
 int honouredSF=honourPreferred?(parent->preferredsfs|TsampleFormat::SF_PCM24):TsampleFormat::SF_ALL;
 if (supSF&honouredSF)
  supSF&=honouredSF;
 if (sf.sf&supSF)
  return (void*)bufIn;
 TsampleFormat sfIn=sf;
 sf.sf=TsampleFormat::sf_bestMatch(sf.sf,supSF);
 return convertTo(sfIn,bufIn,numsamples,sf,samplestoalloc);
}

bool TaudioFilter::is(const TsampleFormat &fmt,const TfilterSettingsAudio *cfg)
{
 return cfg->is && cfg->show;
}

bool TaudioFilter::getOutputFmt(TsampleFormat &sf,const TfilterSettingsAudio *cfg)
{
 if (!is(sf,cfg)) return false;
 bool honourPreferred=true;
 int supSF=getSupportedFormats(cfg,&honourPreferred);
 int honouredSF=honourPreferred?(parent->preferredsfs|TsampleFormat::SF_PCM24):TsampleFormat::SF_ALL;
 if (supSF&honouredSF)
  supSF&=honouredSF;
 if ((sf.sf&supSF)==0)
  sf.sf=TsampleFormat::sf_bestMatch(sf.sf,supSF);
 return true;
}

HRESULT TaudioFilter::flush(TfilterQueue::iterator it,TsampleFormat &fmt,const TfilterSettingsAudio *cfg0)
{
 return parent->deliverSamples(++it,fmt,NULL,0);
}

⌨️ 快捷键说明

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