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; }
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; }