Example #1
0
TaudioCodec* TaudioCodec::getDecLib(CodecID codecId,IffdshowBase *deci,IdecAudioSink *sink)
{
    TaudioCodec *movie;
    if      (lavc_codec   (codecId)) {
        movie=new TaudioCodecLibavcodec(deci,sink);
    } else if (raw_codec    (codecId)) {
        movie=new TaudioCodecUncompressed(deci,sink);
    } else if (codecId==CODEC_ID_LIBMAD) {
        movie=new TaudioCodecLibMAD(deci,sink);
    } else if (codecId==CODEC_ID_LIBFAAD) {
        movie=new TaudioCodecLibFAAD(deci,sink);
    } else if (codecId==CODEC_ID_AVISYNTH) {
        movie=new TaudioCodecAvisynth(deci,sink);
    } else if (codecId==CODEC_ID_LIBA52) {
        movie=new TaudioCodecLiba52(deci,sink);
    } else if (codecId==CODEC_ID_LIBDTS) {
        movie=new TaudioCodecLibDTS(deci,sink);
    } else if (spdif_codec(codecId) || bitstream_codec(codecId)) {
        movie=new TaudioCodecBitstream(deci,sink);
    } else {
        return NULL;
    }
    movie->codecId=codecId;
    return movie;
}
Example #2
0
void TquantPage::cfg2dlg(void)
{
    int is = deciE->isQuantControlActive();

    SetDlgItemInt(m_hwnd, IDC_ED_Q_I_MIN, cfgGet(IDFF_enc_q_i_min), FALSE);
    SetDlgItemInt(m_hwnd, IDC_ED_Q_I_MAX, cfgGet(IDFF_enc_q_i_max), FALSE);
    setText(IDC_ED_I_QUANTFACTOR, _l("%.2f"), float(cfgGet(IDFF_enc_i_quant_factor) / 100.0));
    setText(IDC_ED_I_QUANTOFFSET, _l("%.2f"), float(cfgGet(IDFF_enc_i_quant_offset) / 100.0));
    static const int idIquants[] = {IDC_LBL_Q_I, IDC_ED_Q_I_MIN, IDC_ED_Q_I_MAX, 0};
    setDlgItemText(m_hwnd, IDC_LBL_Q_P, _(IDC_LBL_Q_P, _l("P frames")));
    enable(is && 1, idIquants);
    static const int idIoffset[] = {IDC_LBL_I_QUANTFACTOR, IDC_LBL_I_QUANTOFFSET, IDC_ED_I_QUANTFACTOR, IDC_ED_I_QUANTOFFSET, 0};
    enable(lavc_codec(codecId) && codecId != AV_CODEC_ID_MJPEG, idIoffset);

    bias2dlg();

    static const int idDCT[] = {IDC_LBL_DCT_ALGO, IDC_CBX_DCT_ALGO, 0};
    cbxSetCurSel(IDC_CBX_DCT_ALGO, cfgGet(IDFF_enc_dct_algo));
    enable(sup_lavcQuant(codecId), idDCT);

    qns2dlg();
}
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;
}