STDMETHODIMP CLAVVideoSubtitleInputPin::Receive(IMediaSample* pSample) { CAutoLock lock(&m_csReceive); HRESULT hr = S_OK; Decrypt(pSample); ASSERT(m_pProvider); hr = CBaseInputPin::Receive(pSample); if (hr == S_OK) { long len = pSample->GetActualDataLength(); BYTE *pBuffer = nullptr; if (FAILED(hr = pSample->GetPointer(&pBuffer))) { DbgLog((LOG_TRACE, 10, L"CLAVVideoSubtitleInputPin::Receive() GetPointer failed")); return S_OK; } StripPacket(pBuffer, len); REFERENCE_TIME rtStart, rtStop; hr = pSample->GetTime(&rtStart, &rtStop); if (hr == VFW_S_NO_STOP_TIME) { rtStop = AV_NOPTS_VALUE; } else if (FAILED(hr)) { rtStart = rtStop = AV_NOPTS_VALUE; } m_pProvider->Decode(pBuffer, len, rtStart, rtStop); } return S_OK; }
HRESULT TffdshowVideoInputPin::decompress(IMediaSample *pSample, long *srcLen) { BYTE *bitstream; if (pSample->GetPointer(&bitstream) != S_OK) { *srcLen = -1; return S_FALSE; } *srcLen = pSample->GetActualDataLength(); if (bitstream && strippacket) { StripPacket(bitstream, *srcLen); } return video->decompress(bitstream, *srcLen, pSample); }
HRESULT TtextInputPin::Receive(IMediaSample *pSample) { HRESULT hr; ASSERT(pSample); hr=CDeCSSInputPin::Receive(pSample); if (FAILED(hr)) { return hr; } AM_MEDIA_TYPE* pmt=NULL; if (SUCCEEDED(pSample->GetMediaType(&pmt)) && pmt) { CMediaType mt(*pmt); bool oldfirsttime=firsttime; SetMediaType(&mt); DeleteMediaType(pmt); firsttime=oldfirsttime; } if (firsttime) { DPRINTF(_l("TtextInputPin::Receive initSubtitles")); firsttime=false; found=filter->initSubtitles(id,type,extradata,extradatasize); } REFERENCE_TIME t1=-1,t2=-1; pSample->GetTime(&t1,&t2); BYTE *data; pSample->GetPointer(&data); long datalen=pSample->GetActualDataLength(); if (Tsubreader::isDVDsub(type)) { StripPacket(data,datalen); } //int sStart=float(t1+segmentStart)/REF_SECOND_MULT,sStop=float(t2+segmentStart)/REF_SECOND_MULT; //data[datalen]='\0'; //DPRINTF(_l("%02i:%02i:%02i-%02i:%02i:%02i %s"),sStart/3600,(sStart%3600)/60,sStart%60,sStop/3600,(sStop%3600)/60,sStop%60,(const char_t*)text<char_t>((const char*)data)); if (data && datalen>0) { filter->addSubtitle(id,t1+segmentStart,t2+segmentStart,data,datalen,utf8); } return S_OK; }
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; }