tffdshowdecaudio.cpp.svn-base

来自「ffshow源码」· SVN-BASE 代码 · 共 827 行 · 第 1/2 页

SVN-BASE
827
字号
 firsttransform=true; ft1=ft2=0; return CTransformFilter::StartStreaming();}HRESULT TffdshowDecAudio::BeginFlush(){ DPRINTF(_l("TffdshowDecAudio::BeginFlush")); return CTransformFilter::BeginFlush();}HRESULT TffdshowDecAudio::EndFlush(void){ DPRINTF(_l("TffdshowDecAudio::EndFlush")); CAutoLock cAutoLock(&m_csReceive); return CTransformFilter::EndFlush();}HRESULT TffdshowDecAudio::EndOfStream(void){ DPRINTF(_l("TffdshowDecAudio::EndOfStream")); CAutoLock cAutoLock(&m_csReceive); return CTransformFilter::EndOfStream();}HRESULT TffdshowDecAudio::NewSegment(REFERENCE_TIME tStart,REFERENCE_TIME tStop,double dRate){ DPRINTF(_l("TffdshowDecAudio::NewSegment")); CAutoLock cAutoLock(&m_csReceive); return TffdshowDec::NewSegment(tStart,tStop,dRate);}HRESULT TffdshowDecAudio::Receive(IMediaSample* pIn){ if (firsttransform)  {   firsttransform=false;   onTrayIconChange(0,0);  } return S_OK;}HRESULT TffdshowDecAudio::onGraphRemove(void){  //if (inpin->audio) delete inpin->audio;inpin->audio=NULL; if (audioFilters) delete audioFilters;audioFilters=NULL; currentOutsf.reset(); return TffdshowDec::onGraphRemove();}STDMETHODIMP TffdshowDecAudio::deliverDecodedSample(const TffdshowDecAudioInputPin *pin,void *buf,size_t numsamples,const TsampleFormat &fmt,float postgain){ REFERENCE_TIME rtDurDec=REF_SECOND_MULT*numsamples/fmt.freq; m_rtStartDec+=rtDurDec; if (!audioFilters) audioFilters=new TaudioFiltersPlayer(this,this); HRESULT res=audioFilters->process(fmt,buf,numsamples,presetSettings,prevpostgain=postgain); return res;}HRESULT TffdshowDecAudio::flushDecodedSamples(const TffdshowDecAudioInputPin *pin,float postgain){ if (!audioFilters) audioFilters=new TaudioFiltersPlayer(this,this); return audioFilters->process(TsampleFormat(),NULL,0,presetSettings,prevpostgain);}STDMETHODIMP TffdshowDecAudio::deliverProcessedSample(const void *buf,size_t numsamples,const TsampleFormat &outsf0){ sendOnFrameMsg(); if (numsamples==0) return S_OK; currentOutsf=outsf0; CMediaType mt=currentOutsf.toCMediaType(alwaysextensible); WAVEFORMATEX *wfe=(WAVEFORMATEX*)mt.Format(); HRESULT hr=S_OK; if (!fileout && FAILED(hr=ReconnectOutput(numsamples,mt)))  return hr;   comptr<IMediaSample> pOut;  BYTE *dst=NULL; if (FAILED(getDeliveryBuffer(&pOut,&dst)))  return E_FAIL; REFERENCE_TIME rtDurProc=REF_SECOND_MULT*numsamples/currentOutsf.freq; REFERENCE_TIME rtStart=m_rtStartProc,rtStop=m_rtStartProc+rtDurProc; m_rtStartProc+=rtDurProc; if (rtStart<0)  return S_OK; if (!fileout && hr==S_OK)  {   m_pOutput->SetMediaType(&mt);   pOut->SetMediaType(&mt);  } pOut->SetTime(&rtStart,&rtStop); if (!isTmpgEnc)  pOut->SetMediaTime(NULL,NULL); // this should cause subsequent calls to GetMediaType to return error, but actually they return S_OK and zero start and stop times pOut->SetPreroll(FALSE); pOut->SetDiscontinuity(discontinuity);discontinuity=false; pOut->SetSyncPoint(TRUE); size_t dstlen=numsamples*currentOutsf.nchannels*currentOutsf.bitsPerSample()/8; pOut->SetActualDataLength((long)dstlen); memcpy(dst,buf,dstlen); if (fileout)  {   ft2+=dstlen;   pOut->SetTime(&ft1,&ft2);   ft1+=dstlen;  } return m_pOutput->Deliver(pOut); }STDMETHODIMP TffdshowDecAudio::deliverSampleSPDIF(void *buf,size_t size,int bit_rate,BYTE type,int incRtDec){ HRESULT hr=S_OK;; currentOutsf.sf=TsampleFormat::SF_AC3; CMediaType mt=TsampleFormat::createMediaTypeSPDIF(); WAVEFORMATEX *wfe=(WAVEFORMATEX*)mt.Format(); size_t length; if (!fileout)  {   length=0;   while (length<size+sizeof(WORD)*4) length+=0x800;   unsigned int size2=(unsigned int)(int64_t(1)*wfe->nBlockAlign*wfe->nSamplesPerSec*size*8/bit_rate);   while (length<size2) length+=0x800;  } else  length=size; if (!fileout && FAILED(hr=ReconnectOutput(length/wfe->nBlockAlign,mt)))  return hr; comptr<IMediaSample> pOut; BYTE *pDataOut=NULL; if (FAILED(getDeliveryBuffer(&pOut,&pDataOut)))  return E_FAIL; REFERENCE_TIME rtDur=REF_SECOND_MULT*size*8/bit_rate; REFERENCE_TIME rtStart=m_rtStartProc,rtStop=m_rtStartProc+rtDur; DPRINTF(_l("pin:%I64i startDec:%I64i"),rtStart,m_rtStartDec); m_rtStartProc+=rtDur;if (incRtDec) m_rtStartDec+=rtDur; if (rtStart<0)  return S_OK; if (!fileout && hr==S_OK)  {   m_pOutput->SetMediaType(&mt);   pOut->SetMediaType(&mt);  } pOut->SetTime(&rtStart,&rtStop); pOut->SetMediaTime(NULL,NULL); pOut->SetPreroll(FALSE); pOut->SetDiscontinuity(discontinuity);discontinuity=false; pOut->SetSyncPoint(TRUE); pOut->SetActualDataLength((long)length); if (!fileout)  {   WORD *pDataOutW=(WORD*)pDataOut;   pDataOutW[0]=0xf872;   pDataOutW[1]=0x4e1f;   pDataOutW[2]=type;   pDataOutW[3]=WORD(size*8);   _swab((char*)buf,(char*)&pDataOutW[4],(int)size);  } else  {   memcpy(pDataOut,buf,length);   ft2+=length;   pOut->SetTime(&ft1,&ft2);   ft1+=length;  } HRESULT res=m_pOutput->Deliver(pOut); pOut=NULL; return res;}STDMETHODIMP TffdshowDecAudio::getMovieSource(const TaudioCodec* *moviePtr){ return inpin->getMovieSource(moviePtr);}STDMETHODIMP TffdshowDecAudio::inputSampleFormatDescription(char_t *buf,size_t buflen){ if (!buf || buflen==0) return E_POINTER; if (!insf) return E_UNEXPECTED; insf.description(buf,buflen); return S_OK;}STDMETHODIMP TffdshowDecAudio::inputSampleFormat(unsigned int *nchannels,unsigned int *freq){ if (!nchannels && !freq) return E_POINTER; if (!insf) return E_UNEXPECTED; if (nchannels) *nchannels=insf.nchannels; if (freq) *freq=insf.freq; return S_OK;}STDMETHODIMP TffdshowDecAudio::currentSampleFormat(unsigned int *nchannels,unsigned int *freq,int *sampleFormat){ if (!nchannels && !freq && !sampleFormat) return E_POINTER; if (!currentOutsf) return E_UNEXPECTED; if (nchannels) *nchannels=currentOutsf.nchannels; if (freq) *freq=currentOutsf.freq; if (sampleFormat) *sampleFormat=currentOutsf.sf; return S_OK;}STDMETHODIMP_(int) TffdshowDecAudio::getJitter(void){ return inpin?inpin->getJitter():0;}STDMETHODIMP TffdshowDecAudio::getWinamp2(Twinamp2* *winamp2ptr){ if (!winamp2ptr) return E_POINTER; if (!winamp2)  winamp2=new Twinamp2(getParamStr2(IDFF_winamp2dir)); *winamp2ptr=winamp2; return S_OK;}void TffdshowDecAudio::onWinamp2dirChange(int paramID,const char_t *valname){ if (winamp2) delete winamp2;winamp2=NULL;}STDMETHODIMP TffdshowDecAudio::getEncoderInfo(char_t *buf,size_t buflen){ return inpin->getEncoderInfo(buf,buflen);}STDMETHODIMP TffdshowDecAudio::getInCodecString(char_t *buf,size_t buflen){ return inpin->getInCodecString(buf,buflen);}STDMETHODIMP_(const char_t*) TffdshowDecAudio::getDecoderName(void){ return inpin->getDecoderName();}STDMETHODIMP TffdshowDecAudio::getOutCodecString(char_t *buf,size_t buflen){ if (!buf) return E_POINTER; if ((inpin && inpin->is_spdif_codec()) || currentOutsf.sf==TsampleFormat::SF_AC3)  {   tsnprintf(buf,buflen,_l("S/PDIF"));   buf[buflen-1]='\0';  } else  currentOutsf.descriptionPCM(buf,buflen); return S_OK;}STDMETHODIMP TffdshowDecAudio::getOutSpeakersDescr(char_t *buf,size_t buflen,int shortcuts){ if (!buf) return E_POINTER; currentOutsf.getSpeakersDescr(buf,buflen,!!shortcuts); return S_OK;}HRESULT TffdshowDecAudio::ReconnectOutput(size_t numsamples, CMediaType& mt){ IPin *cpin=m_pOutput->GetConnected(); if (!cpin) return E_NOINTERFACE; WAVEFORMATEX *wfe=(WAVEFORMATEX*)mt.Format(); long cbBuffer=long(numsamples*wfe->nBlockAlign); if (mt!=m_pOutput->CurrentMediaType() || cbBuffer>actual.cbBuffer)  {   if (cbBuffer>actual.cbBuffer)    {     comptr<IMemInputPin> pPin;     if (FAILED(cpin->QueryInterface(IID_IMemInputPin,(void**)&pPin)))      return E_NOINTERFACE;     HRESULT hr;     comptr<IMemAllocator> pAllocator;     if (FAILED(hr=pPin->GetAllocator(&pAllocator)) || !pAllocator)       return S_OK;//hr; Avisynth GetSample filter can't handle format changes     ALLOCATOR_PROPERTIES props;     if (FAILED(hr=pAllocator->GetProperties(&props)))      return hr;           props.cBuffers=4;     props.cbBuffer=cbBuffer*3/2;     if (FAILED(hr=m_pOutput->DeliverBeginFlush()) ||         FAILED(hr=m_pOutput->DeliverEndFlush()) ||         FAILED(hr=pAllocator->Decommit()) ||         FAILED(hr=pAllocator->SetProperties(&props,&actual)) ||         FAILED(hr=pAllocator->Commit()))       return hr;     if (props.cBuffers>actual.cBuffers || props.cbBuffer>actual.cbBuffer)      {       NotifyEvent(EC_ERRORABORT,hr,0);       return E_FAIL;      }    }   return S_OK;  } return S_FALSE;}STDMETHODIMP_(unsigned int) TffdshowDecAudio::getNumStreams2(void){ return inpins.getNumConnectedInpins();}STDMETHODIMP TffdshowDecAudio::getStreamDescr(unsigned int i,char_t *buf,size_t buflen){ if (i>=inpins.getNumConnectedInpins()) return E_INVALIDARG; if (!buf) return E_POINTER; TffdshowDecAudioInputPin *pin=inpins.getConnectedInpin(i); if (pin && pin->getStreamName(buf,buflen)==S_OK)  return S_OK; else   return E_FAIL;}STDMETHODIMP_(unsigned int) TffdshowDecAudio::getCurrentStream2(void){ CAutoLock cs(&m_csReceive); int ii=0; for (size_t i=0;i<inpins.size();i++)  if (inpins[i]->IsConnected())   if (inpin==inpins[i])    return ii;   else    ii++; return (unsigned int)-1;}STDMETHODIMP TffdshowDecAudio::setCurrentStream(unsigned int i){ if (i>=inpins.getNumConnectedInpins()) return E_INVALIDARG; return setCurrentStream2(inpins.getConnectedInpin(i));}STDMETHODIMP TffdshowDecAudio::setCurrentStream2(TffdshowDecAudioInputPin *newipin){ if (newipin==inpin) return S_OK; //CAutoLock cs(&m_csReceive); if (m_pOutput)  {   m_pOutput->DeliverBeginFlush();   m_pOutput->DeliverEndFlush();  } comptrQ<IMediaControl> _pMC=m_pGraph; OAFilterState _fs=-1; if (_pMC) _pMC->GetState(1000,&_fs); if (_fs==State_Running)  _pMC->Pause(); HRESULT _hr=E_FAIL; comptrQ<IMediaSeeking> _pMS=m_pGraph; LONGLONG _rtNow=0; if (_pMS) _hr=_pMS->GetCurrentPosition(&_rtNow); inpin=newipin; if (SUCCEEDED(_hr) && _pMS)  _hr=_pMS->SetPositions(&_rtNow,AM_SEEKING_AbsolutePositioning,NULL,AM_SEEKING_NoPositioning); if (_fs==State_Running && _pMS)  _pMC->Run(); return _hr;}AM_MEDIA_TYPE* TffdshowDecAudio::getInputMediaType(int lIndex){ TffdshowDecAudioInputPin *pPin=inpins.getConnectedInpin(lIndex); return pPin?::CreateMediaType(&pPin->CurrentMediaType()): ::CreateMediaType(&m_pInput->CurrentMediaType());}STDMETHODIMP_(int) TffdshowDecAudio::getInputBitrate2(void){ return inpin->getInputBitrate();}bool TffdshowDecAudio::isStreamsMenu(void) const{ return isAudioSwitcher || globalSettings->streamsMenu;}void TffdshowDecAudio::addOwnStreams(void){ unsigned int numstreams=inpins.getNumConnectedInpins(); if (numstreams>1)  for (unsigned int i=0;i<numstreams;i++)   streams.push_back(new TstreamAudio(this,1000+i,200,inpins.getConnectedInpin(i)));}DWORD TffdshowDecAudio::TstreamAudio::getFlags(void){ return self->inpin==pPin?AMSTREAMSELECTINFO_ENABLED|AMSTREAMSELECTINFO_EXCLUSIVE:0;}const char_t* TffdshowDecAudio::TstreamAudio::getName(void){ if (pPin->getStreamName(name,256)!=S_OK)  tsprintf(name,_l("In%i"),pPin->number); return name;}bool TffdshowDecAudio::TstreamAudio::action(void){ self->setCurrentStream2(pPin); return false;}STDMETHODIMP TffdshowDecAudio::setAudioFilters(TaudioFilters *audioFiltersPtr){ audioFilters=audioFiltersPtr; return S_OK;}TinfoBase* TffdshowDecAudio::createInfo(void){ return new TinfoDecAudio(this);}

⌨️ 快捷键说明

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