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 + -
显示快捷键?