EContextEstablishTaskResult OnStep( SContextEstablishState& state ) { CBatchSyncVarsSink pSink(m_pChannel); CConsoleVarSender cvarSender( &pSink ); gEnv->pConsole->DumpCVars( &cvarSender, 0 ); pSink.OnAfterVarChange(0); return eCETR_Ok; }
result_type operator()(argument_type pUnk) const { CComQIPtr<INdasTimerEventSink> pSink(pUnk); ATLASSERT(pSink.p); pSink->OnTimer(); }
HRESULT Inpin::Receive(IMediaSample* pInSample) { if (pInSample == 0) return E_INVALIDARG; //#define DEBUG_RECEIVE #ifdef DEBUG_RECEIVE { __int64 start_reftime, stop_reftime; const HRESULT hr = pInSample->GetTime(&start_reftime, &stop_reftime); odbgstream os; os << "vp8dec::inpin::receive: "; os << std::fixed << std::setprecision(3); if (hr == S_OK) os << "start[ms]=" << double(start_reftime) / 10000 << "; stop[ms]=" << double(stop_reftime) / 10000 << "; dt[ms]=" << double(stop_reftime - start_reftime) / 10000; else if (hr == VFW_S_NO_STOP_TIME) os << "start[ms]=" << double(start_reftime) / 10000; os << endl; } #endif Filter::Lock lock; HRESULT hr = lock.Seize(m_pFilter); if (FAILED(hr)) return hr; //#ifdef DEBUG_RECEIVE // wodbgstream os; // os << L"vp8dec::inpin::Receive: THREAD=0x" // << std::hex << GetCurrentThreadId() << std::dec // << endl; //#endif if (!bool(m_pPinConnection)) return VFW_E_NOT_CONNECTED; Outpin& outpin = m_pFilter->m_outpin; if (!bool(outpin.m_pPinConnection)) return S_FALSE; if (!bool(outpin.m_pAllocator)) //should never happen return VFW_E_NO_ALLOCATOR; if (m_pFilter->m_state == State_Stopped) return VFW_E_NOT_RUNNING; if (m_bEndOfStream) return VFW_E_SAMPLE_REJECTED_EOS; if (m_bFlush) return S_FALSE; BYTE* buf; hr = pInSample->GetPointer(&buf); assert(SUCCEEDED(hr)); assert(buf); const long len = pInSample->GetActualDataLength(); assert(len >= 0); const vpx_codec_err_t err = vpx_codec_decode(&m_ctx, buf, len, 0, 0); if (err != VPX_CODEC_OK) { GraphUtil::IMediaEventSinkPtr pSink(m_pFilter->m_info.pGraph); if (bool(pSink)) { lock.Release(); hr = pSink->Notify( EC_STREAM_ERROR_STOPPED, VFW_E_SAMPLE_REJECTED, err); } m_bEndOfStream = true; //clear this when we stop and then start again return S_FALSE; } if (pInSample->IsPreroll() == S_OK) return S_OK; lock.Release(); GraphUtil::IMediaSamplePtr pOutSample; hr = outpin.m_pAllocator->GetBuffer(&pOutSample, 0, 0, 0); if (FAILED(hr)) return S_FALSE; assert(bool(pOutSample)); hr = lock.Seize(m_pFilter); if (FAILED(hr)) return hr; if (m_pFilter->m_state == State_Stopped) return VFW_E_NOT_RUNNING; if (!bool(outpin.m_pPinConnection)) //should never happen return S_FALSE; if (!bool(outpin.m_pInputPin)) //should never happen return S_FALSE; vpx_codec_iter_t iter = 0; vpx_image_t* const f = vpx_codec_get_frame(&m_ctx, &iter); if (f == 0) return S_OK; AM_MEDIA_TYPE* pmt; hr = pOutSample->GetMediaType(&pmt); if (SUCCEEDED(hr) && (pmt != 0)) { assert(outpin.QueryAccept(pmt) == S_OK); outpin.m_connection_mtv.Clear(); outpin.m_connection_mtv.Add(*pmt); MediaTypeUtil::Free(pmt); pmt = 0; } const AM_MEDIA_TYPE& mt = outpin.m_connection_mtv[0]; assert(mt.formattype == FORMAT_VideoInfo); assert(mt.cbFormat >= sizeof(VIDEOINFOHEADER)); assert(mt.pbFormat); const VIDEOINFOHEADER& vih = (VIDEOINFOHEADER&)(*mt.pbFormat); const BITMAPINFOHEADER& bmih = vih.bmiHeader; //Y const BYTE* pInY = f->planes[PLANE_Y]; assert(pInY); unsigned int wIn = f->d_w; unsigned int hIn = f->d_h; BYTE* pOutBuf; hr = pOutSample->GetPointer(&pOutBuf); assert(SUCCEEDED(hr)); assert(pOutBuf); BYTE* pOut = pOutBuf; const int strideInY = f->stride[PLANE_Y]; LONG strideOut = bmih.biWidth; assert(strideOut); assert((strideOut % 2) == 0); //? for (unsigned int y = 0; y < hIn; ++y) { memcpy(pOut, pInY, wIn); pInY += strideInY; pOut += strideOut; } strideOut /= 2; wIn = (wIn + 1) / 2; hIn = (hIn + 1) / 2; const BYTE* pInV = f->planes[PLANE_V]; assert(pInV); const int strideInV = f->stride[PLANE_V]; const BYTE* pInU = f->planes[PLANE_U]; assert(pInU); const int strideInU = f->stride[PLANE_U]; if (mt.subtype == MEDIASUBTYPE_YV12) { //V for (unsigned int y = 0; y < hIn; ++y) { memcpy(pOut, pInV, wIn); pInV += strideInV; pOut += strideOut; } //U for (unsigned int y = 0; y < hIn; ++y) { memcpy(pOut, pInU, wIn); pInU += strideInU; pOut += strideOut; } } else { //U for (unsigned int y = 0; y < hIn; ++y) { memcpy(pOut, pInU, wIn); pInU += strideInU; pOut += strideOut; } //V for (unsigned int y = 0; y < hIn; ++y) { memcpy(pOut, pInV, wIn); pInV += strideInV; pOut += strideOut; } } __int64 st, sp; hr = pInSample->GetTime(&st, &sp); if (FAILED(hr)) { hr = pOutSample->SetTime(0, 0); assert(SUCCEEDED(hr)); } else if (hr == S_OK) { hr = pOutSample->SetTime(&st, &sp); assert(SUCCEEDED(hr)); } else { hr = pOutSample->SetTime(&st, 0); assert(SUCCEEDED(hr)); } hr = pOutSample->SetSyncPoint(TRUE); assert(SUCCEEDED(hr)); hr = pOutSample->SetPreroll(FALSE); assert(SUCCEEDED(hr)); const ptrdiff_t lenOut_ = pOut - pOutBuf; const long lenOut = static_cast<long>(lenOut_); hr = pOutSample->SetActualDataLength(lenOut); assert(SUCCEEDED(hr)); hr = pInSample->IsDiscontinuity(); hr = pOutSample->SetDiscontinuity(hr == S_OK); hr = pOutSample->SetMediaTime(0, 0); lock.Release(); return outpin.m_pInputPin->Receive(pOutSample); }