LRESULT Twindow::TwidgetSubclassChb::onContextMenu(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { if (self->tr->translateMode) { return TwidgetSubclass::onContextMenu(hwnd,uMsg,wParam,lParam); } static const char_t *menu[]= {_l("Reset"),NULL}; if (self->selectFromMenu(menu,0)==0) if (self->deci->resetParam(ff_abs(bind->idff))!=S_OK) { return 0; } else if (bind->onClick) { (self->*bind->onClick)(); } else { self->cfg2dlg(); } return 0; }
template<class sample_t> void TaudioFilterVolume::volume(sample_t* const samples, size_t numsamples, const TsampleFormat &fmt, const TvolumeSettings *cfg) { if (cfg->is) { if (!cfg->normalize) { if (isVol) { typedef void (*TprocessVol)(sample_t * const samples, size_t numsamples, const int * volumes); static const TprocessVol processVol[9] = { NULL, &Tmultiply<1>::processVol, &Tmultiply<2>::processVol, &Tmultiply<3>::processVol, &Tmultiply<4>::processVol, &Tmultiply<5>::processVol, &Tmultiply<6>::processVol, &Tmultiply<7>::processVol, &Tmultiply<8>::processVol }; processVol[fmt.nchannels](samples, numsamples, volumes); } } else { size_t len = numsamples * fmt.nchannels; float max = 0.0f; for (size_t i = 0; i < len; i++) { float tmp = float(samples[i]); //max = max(max, tmp) max = max > tmp ? max : tmp; } //upper = min(mul, cfg->normalizeMax/100.0f) float upper = mul > (cfg->normalizeMax / 100.0f) ? (cfg->normalizeMax / 100.0f) : mul; // Evaluate an adequate 'mul' coefficient based on previous state, current samples level, etc if (mul > TsampleFormatInfo<sample_t>::max() / max || mul > cfg->normalizeMax / 100.0f) { mul = limit((float)(TsampleFormatInfo<sample_t>::max() / max), MUL_MIN, upper); } else { if (cfg->normalizeRegainVolume) { // here we make sure that the current sound level (max * mul) will not rise above 'RegainThreshold'. if (max < (TsampleFormatInfo<sample_t>::max() / mul) * RegainThreshold) { // note that in one second, in average, the sum of ((float)numsamples / fmt.freq) will be 1. float step = MUL_STEP * ((float)numsamples / fmt.freq); if (mul + step <= cfg->normalizeMax / 100.0f) { mul += step; } else { // mul + step > cfg->normalizeMax/100.0f // make sure that the last increment will be performed, even if it's smaller than 'step' // otherwise, current amplification could be displayed as 399% instead of 400%, for example. mul = cfg->normalizeMax / 100.0f; } } } } // Scale & clamp the samples typedef void (*TprocessMul)(sample_t * const samples, size_t numsamples, const int * volumes, float mul); static const TprocessMul processMul[9] = { NULL, &Tmultiply<1>::processMul, &Tmultiply<2>::processMul, &Tmultiply<3>::processMul, &Tmultiply<4>::processMul, &Tmultiply<5>::processMul, &Tmultiply<6>::processMul, &Tmultiply<7>::processMul, &Tmultiply<8>::processMul }; processMul[fmt.nchannels](samples, numsamples, volumes, mul); } if (numsamples > 0 && deci->getParam2(IDFF_showCurrentVolume) && deci->getCfgDlgHwnd()) { int64_t sum[8]; memset(sum, 0, sizeof(sum)); for (size_t i = 0; i < numsamples * fmt.nchannels;) { for (unsigned int ch = 0; ch < fmt.nchannels; ch++, i++) { sum[ch] += int64_t((int64_t)65536 * ff_abs(samples[i])); } } CAutoLock lock(&csVolumes); for (unsigned int i = 0; i < fmt.nchannels; i++) { storedvolumes.volumes[i] = int((sum[i] / numsamples) / int64_t(TsampleFormatInfo<sample_t>::max())); } storedvolumes.have = true; } } }
STDMETHODIMP TffdshowDecAudioInputPin::Receive(IMediaSample* pIn) { if (this != filter->inpin) { //DPRINTF(_l("TffdshowDecAudioInputPin::Receive Not right pin : this = %u, filter inpin = %u"), this, filter->inpin); if (m_useBlock) { m_evBlock.Wait(); } else { return S_FALSE; } } if (!isActive()) { //DPRINTF(_l("TffdshowDecAudioInputPin::Receive Pin unlocked : this = %u, filter inpin = %u"), this, filter->inpin); if (this != filter->inpin) { return S_FALSE; } return E_FAIL; } //CAutoLock cAutoLock(&m_csReceive); if (filter->IsStopped()) { return S_FALSE; } HRESULT hr = TinputPin::Receive(pIn); if (hr != S_OK) { return hr; } AM_SAMPLE2_PROPERTIES* const pProps = SampleProps(); if (pProps->dwStreamId != AM_STREAM_MEDIA) { return filter->m_pOutput->Deliver(pIn); } AM_MEDIA_TYPE *pmt = NULL; if (SUCCEEDED(pIn->GetMediaType(&pmt)) && pmt) { CMediaType mt(*pmt); SetMediaType(&mt); DeleteMediaType(pmt); pmt = NULL; } BYTE *src = NULL; if (FAILED(hr = pIn->GetPointer(&src))) { return hr; } long srclen = pIn->GetActualDataLength(); if (strippacket) { StripPacket(src, srclen); } REFERENCE_TIME rtStart = _I64_MIN, rtStop = _I64_MIN; hr = pIn->GetTime(&rtStart, &rtStop); if (hr == S_OK) { insample_rtStart = rtStart; insample_rtStop = rtStop; //DPRINTF(_l("TffdshowDecAudioInputPin::Receive audio sample start duration %I64i %I64i"),rtStart,rtStop-rtStart); } if (pIn->IsDiscontinuity() == S_OK) { filter->discontinuity = true; buf.clear(); if (FAILED(hr)) { return S_OK; } filter->m_rtStartDec = filter->m_rtStartProc = rtStart; } if (SUCCEEDED(hr)) { REFERENCE_TIME j = filter->m_rtStartDec - rtStart; jitter = int(j); if ((uint64_t)ff_abs(j) > 100 * (REF_SECOND_MULT / 1000) // +-100ms jitter is allowed for now && codecId != AV_CODEC_ID_FLAC && codecId != AV_CODEC_ID_TTA && codecId != AV_CODEC_ID_WAVPACK && codecId != AV_CODEC_ID_TRUEHD && codecId != AV_CODEC_ID_MLP && codecId != AV_CODEC_ID_COOK && !bitstream_codec(codecId) && filter->getParam2(IDFF_audio_decoder_JitterCorrection)) { DPRINTF(_l("jitter correction")); buf.clear(); newSrcBuffer.clear(); filter->m_rtStartDec = filter->m_rtStartProc = rtStart; if (audioParser) { audioParser->NewSegment(); } } } buf.append(src, srclen); buf.reserve(buf.size() + 32); AVCodecID newCodecId = codecId; TaudioParserData audioParserData; // Before sending data to the decoder, we parse it switch (codecId) { case AV_CODEC_ID_DTS: case CODEC_ID_LIBDTS: case CODEC_ID_SPDIF_DTS: case AV_CODEC_ID_AC3: case AV_CODEC_ID_EAC3: case AV_CODEC_ID_MLP: case AV_CODEC_ID_TRUEHD: case CODEC_ID_LIBA52: case CODEC_ID_SPDIF_AC3: case CODEC_ID_PCM: case CODEC_ID_BITSTREAM_TRUEHD: case CODEC_ID_BITSTREAM_DTSHD: // Search for DTS in Wav only if option is checked if (codecId == CODEC_ID_PCM && !searchdts) { break; } // Do not search for DTS in PCM in next frames (otherwise DTS syncword maybe wrongly detected) searchdts = false; newCodecId = audioParser->parseStream(buf.size() ? &buf[0] : NULL, (int)buf.size(), &newSrcBuffer); if (newCodecId == AV_CODEC_ID_NONE) { newSrcBuffer.clear(); break; } // Get updated data from the parser audioParserData = audioParser->getParserData(); // Clear input buffer (if 2 source buffers are coexisting, sound will be garbled) buf.clear(); if (codecId != newCodecId) { DPRINTF(_l("TffdshowDecAudioInputPin : switching codec from %s to %s"), getCodecName(codecId), getCodecName(newCodecId)); codecId = newCodecId; // Update input sample format from (corrected or updated) parser data if (audioParserData.channels != 0) { filter->insf.setChannels(audioParserData.channels); } if (audioParserData.sample_rate != 0) { filter->insf.freq = audioParserData.sample_rate; } if (audioParserData.sample_format != 0) { filter->insf.sf = audioParserData.sample_format; } filter->insf.alternateSF = audioParserData.alternateSampleFormat; // Sample format from audio parser data TsampleFormat fmt = TsampleFormat( (audioParserData.sample_format != 0) ? audioParserData.sample_format : TsampleFormat::SF_PCM16, audioParserData.sample_rate, audioParserData.channels); // Reinitialize the audio codec according to the new codecId DPRINTF(_l("TffdshowDecAudioInputPin::Receive : Initialize audio codec %s"), getCodecName(codecId)); if (audio) { delete audio; codec = audio = NULL; } codec = audio = TaudioCodec::initSource(filter, this, codecId, filter->insf, filter->insf.toCMediaType()); if (!audio) { return false; } jitter = 0; } // Update libavcodec context with correct channels and bitrate read from parser if (lavc_codec(codecId)) { TaudioCodecLibavcodec *audioCodecLibavcodec = (TaudioCodecLibavcodec*)audio; if (audioCodecLibavcodec) { if (audioParserData.channels != 0) { audioCodecLibavcodec->avctx->channels = audioParserData.channels; } if (audioParserData.bit_rate != 0) { audioCodecLibavcodec->avctx->bit_rate = audioParserData.bit_rate; } if (audioParserData.sample_rate != 0) { audioCodecLibavcodec->avctx->sample_rate = audioParserData.sample_rate; } } } if (audioParserData.channels != 0) { filter->insf.setChannels(audioParserData.channels); } if (audioParserData.sample_rate != 0) { filter->insf.freq = audioParserData.sample_rate; } if (audioParserData.sample_format != 0) { filter->insf.sf = audioParserData.sample_format; } newSrcBuffer.reserve(newSrcBuffer.size() + 32); hr = audio->decode(newSrcBuffer); if (hr == S_FALSE) { return S_OK; } else if (hr != S_OK) { DPRINTF(_l("TffdshowDecAudioInputPin::Receive decode failed pin %u (%lx)"), this, hr); } return hr; break; default: // Decode data hr = audio->decode(buf); if (hr == S_FALSE) { return S_OK; } else if (hr != S_OK) { DPRINTF(_l("TffdshowDecAudioInputPin::Receive decode failed pin %u (%lx)"), this, hr); } return hr; break; } hr = audio->decode(buf); if (hr == S_FALSE) { return S_OK; } else if (hr != S_OK) { DPRINTF(_l("TffdshowDecAudioInputPin::Receive decode failed pin %u (%lx)"), this, hr); } return hr; }