コード例 #1
0
ファイル: Twindow.cpp プロジェクト: JERUKA9/ffdshow-tryouts
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;
}
コード例 #2
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;
        }
    }
}
コード例 #3
0
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;
}