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

📄 tsampleformat.cpp.svn-base

📁 ffshow源码
💻 SVN-BASE
字号:
/* * Copyright (c) 2004-2006 Milan Cutka * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */#include "stdafx.h"#include "TsampleFormat.h"#include "ffdshow_mediaguids.h"#include "vorbis/vorbisformat.h"#include "dsutil.h"const int TsampleFormat::standardChannelMasks[]={ SPEAKER_FRONT_CENTER, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_BACK_CENTER, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT};TsampleFormat::TsampleFormat(const WAVEFORMATEX &wfex,bool wfextcheck,const GUID *subtype):pcm_be(false){ init(wfex,wfextcheck,subtype);}void TsampleFormat::init(const WAVEFORMATEX &wfex,bool wfextcheck,const GUID *subtype){ if (wfextcheck && wfex.wFormatTag==WAVE_FORMAT_EXTENSIBLE)  init(*(const WAVEFORMATEXTENSIBLE*)&wfex,subtype); else  {   freq=wfex.nSamplesPerSec;   setChannels(wfex.nChannels,0);   if (wfex.wFormatTag==WAVE_FORMAT_IEEE_FLOAT)    sf=SF_FLOAT32;   else if (wfex.wFormatTag==WAVE_FORMAT_DOLBY_AC3_SPDIF)    sf=SF_AC3;   else if (subtype)    {     if (*subtype==MEDIASUBTYPE_IN32 || *subtype==MEDIASUBTYPE_in32 || *subtype==MEDIASUBTYPE_IN24 || *subtype==MEDIASUBTYPE_in24 || *subtype==MEDIASUBTYPE_FL32 || *subtype==MEDIASUBTYPE_fl32 || *subtype==MEDIASUBTYPE_FL64 || *subtype==MEDIASUBTYPE_fl64)      {       if (*subtype==MEDIASUBTYPE_IN32 || *subtype==MEDIASUBTYPE_in32)        sf=SF_PCM32;       else if (*subtype==MEDIASUBTYPE_IN24 || *subtype==MEDIASUBTYPE_in24)        sf=SF_PCM24;        else if (*subtype==MEDIASUBTYPE_FL32 || *subtype==MEDIASUBTYPE_fl32)        sf=SF_FLOAT32;        else if (*subtype==MEDIASUBTYPE_FL64 || *subtype==MEDIASUBTYPE_fl64)        sf=SF_FLOAT64;        Textradata extradata(wfex);       if (extradata.data)        {         const uint8_t *enda=(const uint8_t*)memnstr(extradata.data,extradata.size,"enda"); //TODO: properly parse headers         if (enda && *(uint16_t*)(enda+4)==0)          pcm_be=true;        }      }       else if (*subtype==MEDIASUBTYPE_twos || *subtype==MEDIASUBTYPE_TWOS)       {       sf=SF_PCM16;       pcm_be=true;      }     }    else    switch (wfex.wBitsPerSample)     {      case 8:sf=SF_PCM8;break;      case 0:      case 16:      default:sf=SF_PCM16;break;      case 20:sf=SF_LPCM20;break;      case 24:sf=SF_PCM24;break;      case 32:sf=SF_PCM32;break;     }    dolby=DOLBY_NO;  }}TsampleFormat::TsampleFormat(const WAVEFORMATEXTENSIBLE &wfexten,const GUID *subtype):pcm_be(false){ init(wfexten,subtype);}void TsampleFormat::init(const WAVEFORMATEXTENSIBLE &wfexten,const GUID *subtype){ init(wfexten.Format,false,subtype); setChannels(wfexten.Format.nChannels,wfexten.dwChannelMask); if (wfexten.SubFormat==MEDIASUBTYPE_IEEE_FLOAT)  sf=SF_FLOAT32;}TsampleFormat::TsampleFormat(const VORBISFORMAT &vf):pcm_be(false){ init(vf);}void TsampleFormat::init(const VORBISFORMAT &vf){ freq=vf.nSamplesPerSec; sf=SF_PCM16; setChannels(vf.nChannels,0); dolby=DOLBY_NO;}TsampleFormat::TsampleFormat(const VORBISFORMAT2 &vf2):pcm_be(false){ init(vf2);}void TsampleFormat::init(const VORBISFORMAT2 &vf2){ freq=vf2.SamplesPerSec; switch (vf2.BitsPerSample)  {   case 0:   case 16:   default:sf=SF_PCM16;break;   case 24:sf=SF_PCM24;break;   case 32:sf=SF_PCM32;break;  } setChannels(vf2.Channels,0); dolby=DOLBY_NO;}TsampleFormat::TsampleFormat(const VORBISFORMATILL &vfIll):pcm_be(false){ init(vfIll);}void TsampleFormat::init(const VORBISFORMATILL &vfIll){ freq=vfIll.samplesPerSec; sf=SF_PCM16; setChannels(vfIll.numChannels,0); dolby=DOLBY_NO;}TsampleFormat::TsampleFormat(const AM_MEDIA_TYPE &mt):pcm_be(false){ if (mt.formattype==FORMAT_VorbisFormat)  init(*(const VORBISFORMAT*)mt.pbFormat); else if (mt.formattype==FORMAT_VorbisFormat2)  init(*(const VORBISFORMAT2*)mt.pbFormat); else if (mt.formattype==FORMAT_VorbisFormatIll)  init(*(const VORBISFORMATILL*)mt.pbFormat); else if (mt.formattype==FORMAT_WaveFormatEx)  init(*(const WAVEFORMATEX*)mt.pbFormat,true,&mt.subtype); else   {   nchannels=NULL;   sf=SF_NULL;  }}int TsampleFormat::sf_bestMatch(int sfIn,int wantedSFS){ const int *bestsfs=NULL;  switch (sfIn)  {   case SF_PCM16:    {     static const int best[]=      {       SF_PCM32,       SF_PCM24,       SF_FLOAT32,       SF_NULL      };     bestsfs=best;     break;     }   case SF_PCM24:    {     static const int best[]=      {       SF_PCM32,       SF_PCM16,       SF_FLOAT32,       SF_NULL      };     bestsfs=best;     break;     }   case SF_PCM32:    {     static const int best[]=      {       SF_PCM16,       SF_PCM24,       SF_FLOAT32,       SF_NULL      };     bestsfs=best;     break;     }   case SF_PCM8:    {     static const int best[]=      {       SF_PCM16,       SF_PCM32,       SF_NULL      };     bestsfs=best;     break;     }   case SF_FLOAT32:    {     static const int best[]=      {       SF_PCM32,       SF_PCM16,       SF_PCM24,       SF_NULL      };     bestsfs=best;     break;     }   default:return SF_NULL;   }  while (*bestsfs)  {   if (*bestsfs&wantedSFS)    return *bestsfs;   bestsfs++;  }   return SF_NULL;}DWORD TsampleFormat::getPCMformat(const CMediaType &mtIn,DWORD def){ if (*mtIn.FormatType()!=FORMAT_WaveFormatEx)  return def; const WAVEFORMATEX *wfex=(const WAVEFORMATEX*)mtIn.Format(); if (wfex->wFormatTag!=WAVE_FORMAT_EXTENSIBLE && wfex->wFormatTag!=WAVE_FORMAT_PCM && wfex->wFormatTag!=WAVE_FORMAT_IEEE_FLOAT && mtIn.subtype!=MEDIASUBTYPE_RAW)  return def; TsampleFormat sf(mtIn); switch (sf.sf)  {   case SF_NULL:return def;   case SF_PCM8:return WAVE_FORMAT_PCM8;   case SF_PCM16:return WAVE_FORMAT_PCM16;   case SF_PCM24:return WAVE_FORMAT_PCM24;   case SF_PCM32:return WAVE_FORMAT_PCM32;   case SF_FLOAT32:return WAVE_FORMAT_FLOAT32;   case SF_FLOAT64:return WAVE_FORMAT_FLOAT64;  } return def;   }WAVEFORMATEXTENSIBLE TsampleFormat::toWAVEFORMATEXTENSIBLE(bool alwayextensible) const{ WAVEFORMATEXTENSIBLE wfex; memset(&wfex,0,sizeof(wfex)); WAVEFORMATEX *wfe=&wfex.Format; if (sf==SF_FLOAT32)  wfe->wFormatTag=(WORD)WAVE_FORMAT_IEEE_FLOAT; else if (sf==SF_LPCM16)  wfe->wFormatTag=(WORD)WAVE_FORMAT_UNKNOWN; else   wfe->wFormatTag=(WORD)WAVE_FORMAT_PCM; wfe->nChannels=WORD(nchannels); wfe->nSamplesPerSec=freq; wfe->wBitsPerSample=(WORD)bitsPerSample(); wfe->nBlockAlign=WORD(wfe->nChannels*wfe->wBitsPerSample/8); wfe->nAvgBytesPerSec=wfe->nSamplesPerSec*wfe->nBlockAlign; // FIXME: 24/32 bit only seems to work with WAVE_FORMAT_EXTENSIBLE int dwChannelMask; if (channelmask==0 && (sf==TsampleFormat::SF_PCM24 || sf==TsampleFormat::SF_PCM32 || nchannels>2))  dwChannelMask=makeChannelMask2(); else    dwChannelMask=channelmask; if (!alwayextensible && dwChannelMask==standardChannelMasks[nchannels-1])  dwChannelMask=0;   if (dwChannelMask)  {   wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;   wfex.Format.cbSize=sizeof(wfex)-sizeof(wfex.Format);   wfex.dwChannelMask=dwChannelMask;   wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;   wfex.SubFormat=sf==SF_FLOAT32?MEDIASUBTYPE_IEEE_FLOAT:MEDIASUBTYPE_PCM;  } return wfex;}CMediaType TsampleFormat::toCMediaType(bool alwaysextensible) const{ CMediaType mt; /*if (sf==SF_LPCM16)  mt.majortype=MEDIATYPE_MPEG2_PES; else*/  mt.majortype=MEDIATYPE_Audio;  if (sf==SF_FLOAT32)  mt.subtype=MEDIASUBTYPE_IEEE_FLOAT; else if (sf==SF_LPCM16)   mt.subtype=MEDIASUBTYPE_DVD_LPCM_AUDIO; else  mt.subtype=MEDIASUBTYPE_PCM; mt.formattype=FORMAT_WaveFormatEx; WAVEFORMATEXTENSIBLE wfex=toWAVEFORMATEXTENSIBLE(alwaysextensible); mt.SetFormat((BYTE*)&wfex,sizeof(wfex.Format)+wfex.Format.cbSize); return mt;}CMediaType TsampleFormat::createMediaTypeSPDIF(void){ CMediaType mt=TsampleFormat(SF_PCM16,48000,2).toCMediaType(); ((WAVEFORMATEX*)mt.pbFormat)->wFormatTag=WAVE_FORMAT_DOLBY_AC3_SPDIF; return mt;}const char_t* TsampleFormat::getSpeakerName(int speaker,bool shrt){ switch (speaker)  {    case SPEAKER_FRONT_LEFT:return shrt?_l("L"):_l("front left");    case SPEAKER_FRONT_RIGHT:return shrt?_l("R"):_l("front right");    case SPEAKER_FRONT_CENTER:return shrt?_l("C"):_l("front center");    case SPEAKER_LOW_FREQUENCY:return _l("LFE");    case SPEAKER_BACK_LEFT:return shrt?_l("SL"):_l("back left");    case SPEAKER_BACK_RIGHT:return shrt?_l("SR"):_l("back right");    case SPEAKER_FRONT_LEFT_OF_CENTER:return _l("front left of center");    case SPEAKER_FRONT_RIGHT_OF_CENTER:return _l("front right of center");    case SPEAKER_BACK_CENTER:return _l("back center");    case SPEAKER_SIDE_LEFT:return _l("side left");    case SPEAKER_SIDE_RIGHT:return _l("side right");    case SPEAKER_TOP_CENTER:return _l("top center");    case SPEAKER_TOP_FRONT_LEFT:return _l("top front left");    case SPEAKER_TOP_FRONT_CENTER:return _l("top front center");    case SPEAKER_TOP_FRONT_RIGHT:return _l("top front right");    case SPEAKER_TOP_BACK_LEFT:return _l("top back left");    case SPEAKER_TOP_BACK_CENTER:return _l("top back center");    case SPEAKER_TOP_BACK_RIGHT:return _l("top back right");    default:return _l("unknown");  }}void TsampleFormat::getSpeakersDescr(char_t *buf,size_t buflen,bool shrt) const{ buf[0]='\0'; for (unsigned int i=0;i<nchannels;i++)  strncatf(buf,buflen,_l("%s,"),getSpeakerName(speakers[i],shrt)); buf[buflen-1]='\0'; size_t len=strlen(buf); if (len && buf[len-1]==',') buf[len-1]='\0';}

⌨️ 快捷键说明

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