HRESULT CDeinterlacerFilter::DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties) { if (m_pInput->IsConnected() == FALSE) { return E_UNEXPECTED; } BITMAPINFOHEADER bih; ExtractBIH(&m_pOutput->CurrentMediaType(), &bih); pProperties->cBuffers = 1; pProperties->cbBuffer = bih.biSizeImage; pProperties->cbAlign = 1; pProperties->cbPrefix = 0; HRESULT hr; ALLOCATOR_PROPERTIES Actual; if (FAILED(hr = pAllocator->SetProperties(pProperties, &Actual))) { return hr; } return pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer ? E_FAIL : NOERROR; }
HRESULT CDeinterlacerFilter::CheckInputType(const CMediaType* mtIn) { BITMAPINFOHEADER bih; if (!ExtractBIH(mtIn, &bih) /*|| bih.biHeight <= 0*/ || bih.biHeight <= 288) { return E_FAIL; } return mtIn->subtype == MEDIASUBTYPE_YUY2 || mtIn->subtype == MEDIASUBTYPE_UYVY || mtIn->subtype == MEDIASUBTYPE_I420 || mtIn->subtype == MEDIASUBTYPE_YV12 || mtIn->subtype == MEDIASUBTYPE_IYUV || mtIn->subtype == MEDIASUBTYPE_NV12 ? S_OK : E_FAIL; }
HRESULT CBaseVideoFilter::CopyBuffer(BYTE* pOut, BYTE** ppIn, int w, int h, int pitchIn, const GUID& subtype, bool fInterlaced) { BITMAPINFOHEADER bihOut; ExtractBIH(&m_pOutput->CurrentMediaType(), &bihOut); int pitchOut = 0; if (bihOut.biCompression == BI_RGB || bihOut.biCompression == BI_BITFIELDS) { pitchOut = bihOut.biWidth * bihOut.biBitCount >> 3; if (bihOut.biHeight > 0) { pOut += pitchOut * (h - 1); pitchOut = -pitchOut; if (h < 0) { h = -h; } } }
HRESULT CDeinterlacerFilter::Transform(IMediaSample* pIn, IMediaSample* pOut) { HRESULT hr; AM_MEDIA_TYPE* pmt = NULL; if (SUCCEEDED(pOut->GetMediaType(&pmt)) && pmt) { CMediaType mt = *pmt; m_pOutput->SetMediaType(&mt); DeleteMediaType(pmt); } BYTE* pDataIn = NULL; if (FAILED(pIn->GetPointer(&pDataIn)) || !pDataIn) { return S_FALSE; } BYTE* pDataOut = NULL; if (FAILED(hr = pOut->GetPointer(&pDataOut)) || !pDataOut) { return hr; } const CMediaType& mtIn = m_pInput->CurrentMediaType(); const CMediaType& mtOut = m_pOutput->CurrentMediaType(); BITMAPINFOHEADER bihIn, bihOut; ExtractBIH(&mtIn, &bihIn); ExtractBIH(&mtOut, &bihOut); bool fInputFlipped = bihIn.biHeight >= 0 && bihIn.biCompression <= 3; bool fOutputFlipped = bihOut.biHeight >= 0 && bihOut.biCompression <= 3; bool fFlip = fInputFlipped != fOutputFlipped; int bppIn = !(bihIn.biBitCount&7) ? bihIn.biBitCount : 8; int bppOut = !(bihOut.biBitCount&7) ? bihOut.biBitCount : 8; int pitchIn = bihIn.biWidth*bppIn>>3; int pitchOut = bihOut.biWidth*bppOut>>3; BYTE* pDataOut2 = pDataOut; if (fFlip) { pDataOut2 += pitchOut*(bihIn.biHeight-1); pitchOut = -pitchOut; } if (mtIn.subtype == MEDIASUBTYPE_YUY2 || mtIn.subtype == MEDIASUBTYPE_UYVY) { DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn); } else if (mtIn.subtype == MEDIASUBTYPE_I420 || mtIn.subtype == MEDIASUBTYPE_YV12 || mtIn.subtype == MEDIASUBTYPE_IYUV || mtIn.subtype == MEDIASUBTYPE_NV12) { DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn); int sizeIn = bihIn.biHeight*pitchIn, sizeOut = abs(bihOut.biHeight)*pitchOut; pitchIn /= 2; pitchOut /= 2; bihIn.biHeight /= 2; pDataIn += sizeIn; pDataOut += sizeOut; DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn); pDataIn += sizeIn/4; pDataOut += sizeOut/4; DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn); } return S_OK; }
CString CBaseSplitterOutputPin::GetMediaTypeDesc(CAtlArray<CMediaType>& mts, LPCWSTR pName, CBaseFilter* pFilter) { if (mts.IsEmpty()) { return pName; } CLSID clSID; HRESULT hr = pFilter->GetClassID(&clSID); if ((clSID == __uuidof(CMpegSourceFilter)) || (clSID == __uuidof(CMpegSplitterFilter))) { return pName; } CAtlList<CString> Infos; const CMediaType* pmt = &mts[0]; if (pmt->majortype == MEDIATYPE_Video) { const VIDEOINFOHEADER *pVideoInfo = NULL; const VIDEOINFOHEADER2 *pVideoInfo2 = NULL; BOOL bAdd = FALSE; if (pmt->formattype == FORMAT_VideoInfo) { pVideoInfo = GetFormatHelper(pVideoInfo, pmt); } else if (pmt->formattype == FORMAT_MPEGVideo) { Infos.AddTail(L"MPEG"); const MPEG1VIDEOINFO *pInfo = GetFormatHelper(pInfo, pmt); pVideoInfo = &pInfo->hdr; bAdd = TRUE; } else if (pmt->formattype == FORMAT_MPEG2_VIDEO) { const MPEG2VIDEOINFO *pInfo = GetFormatHelper(pInfo, pmt); pVideoInfo2 = &pInfo->hdr; bool bIsAVC = false; bool bIsMPEG2 = false; if (pInfo->hdr.bmiHeader.biCompression == FCC('AVC1') || pInfo->hdr.bmiHeader.biCompression == FCC('H264')) { bIsAVC = true; Infos.AddTail(L"AVC (H.264)"); bAdd = TRUE; } else if (pInfo->hdr.bmiHeader.biCompression == FCC('AMVC')) { bIsAVC = true; Infos.AddTail(L"MVC (Full)"); bAdd = TRUE; } else if (pInfo->hdr.bmiHeader.biCompression == FCC('EMVC')) { bIsAVC = true; Infos.AddTail(L"MVC (Subset)"); bAdd = TRUE; } else if (pInfo->hdr.bmiHeader.biCompression == 0) { Infos.AddTail(L"MPEG2"); bIsMPEG2 = true; bAdd = TRUE; } if (bIsMPEG2) { Infos.AddTail(MPEG2_Profile[pInfo->dwProfile]); } else if (pInfo->dwProfile) { if (bIsAVC) { switch (pInfo->dwProfile) { case 44: Infos.AddTail(L"CAVLC Profile"); break; case 66: Infos.AddTail(L"Baseline Profile"); break; case 77: Infos.AddTail(L"Main Profile"); break; case 88: Infos.AddTail(L"Extended Profile"); break; case 100: Infos.AddTail(L"High Profile"); break; case 110: Infos.AddTail(L"High 10 Profile"); break; case 118: Infos.AddTail(L"Multiview High Profile"); break; case 122: Infos.AddTail(L"High 4:2:2 Profile"); break; case 244: Infos.AddTail(L"High 4:4:4 Profile"); break; case 128: Infos.AddTail(L"Stereo High Profile"); break; default: Infos.AddTail(FormatString(L"Profile %d", pInfo->dwProfile)); break; } } else { Infos.AddTail(FormatString(L"Profile %d", pInfo->dwProfile)); } } if (bIsMPEG2) { Infos.AddTail(MPEG2_Level[pInfo->dwLevel]); } else if (pInfo->dwLevel) { if (bIsAVC) { Infos.AddTail(FormatString(L"Level %1.1f", double(pInfo->dwLevel)/10.0)); } else { Infos.AddTail(FormatString(L"Level %d", pInfo->dwLevel)); } } } else if (pmt->formattype == FORMAT_VIDEOINFO2) { const VIDEOINFOHEADER2 *pInfo = GetFormatHelper(pInfo, pmt); pVideoInfo2 = pInfo; } if (!bAdd) { BITMAPINFOHEADER bih; bool fBIH = ExtractBIH(pmt, &bih); if (fBIH) { CString codecName = CMediaTypeEx::GetVideoCodecName(pmt->subtype, bih.biCompression); if (codecName.GetLength() > 0) { Infos.AddTail(codecName); } } } if (pVideoInfo2) { if (pVideoInfo2->bmiHeader.biWidth && pVideoInfo2->bmiHeader.biHeight) { Infos.AddTail(FormatString(L"%dx%d", pVideoInfo2->bmiHeader.biWidth, pVideoInfo2->bmiHeader.biHeight)); } if (pVideoInfo2->AvgTimePerFrame) { Infos.AddTail(FormatString(L"%.3f fps", 10000000.0/double(pVideoInfo2->AvgTimePerFrame))); } if (pVideoInfo2->dwBitRate) { Infos.AddTail(FormatBitrate(pVideoInfo2->dwBitRate)); } } else if (pVideoInfo) { if (pVideoInfo->bmiHeader.biWidth && pVideoInfo->bmiHeader.biHeight) { Infos.AddTail(FormatString(L"%dx%d", pVideoInfo->bmiHeader.biWidth, pVideoInfo->bmiHeader.biHeight)); } if (pVideoInfo->AvgTimePerFrame) { Infos.AddTail(FormatString(L"%.3f fps", 10000000.0/double(pVideoInfo->AvgTimePerFrame))); } if (pVideoInfo->dwBitRate) { Infos.AddTail(FormatBitrate(pVideoInfo->dwBitRate)); } } } else if (pmt->majortype == MEDIATYPE_Audio) { if (pmt->formattype == FORMAT_WaveFormatEx) { const WAVEFORMATEX *pInfo = GetFormatHelper(pInfo, pmt); if (pmt->subtype == MEDIASUBTYPE_DVD_LPCM_AUDIO) { Infos.AddTail(L"DVD LPCM"); } else if (pmt->subtype == MEDIASUBTYPE_HDMV_LPCM_AUDIO) { const WAVEFORMATEX_HDMV_LPCM *pInfoHDMV = GetFormatHelper(pInfoHDMV, pmt); UNREFERENCED_PARAMETER(pInfoHDMV); Infos.AddTail(L"HDMV LPCM"); } if (pmt->subtype == MEDIASUBTYPE_DOLBY_DDPLUS) { Infos.AddTail(L"Dolby Digital Plus"); } else { switch (pInfo->wFormatTag) { case WAVE_FORMAT_MPEG: { const MPEG1WAVEFORMAT* pInfoMPEG1 = GetFormatHelper(pInfoMPEG1, pmt); int layer = GetHighestBitSet32(pInfoMPEG1->fwHeadLayer) + 1; Infos.AddTail(FormatString(L"MPEG1 - Layer %d", layer)); } break; default: { CString codecName = CMediaTypeEx::GetAudioCodecName(pmt->subtype, pInfo->wFormatTag); if (codecName.GetLength() > 0) { Infos.AddTail(codecName); } } break; } } if (pInfo->nSamplesPerSec) { Infos.AddTail(FormatString(L"%.1f kHz", double(pInfo->nSamplesPerSec)/1000.0)); } if (pInfo->nChannels) { Infos.AddTail(FormatString(L"%d chn", pInfo->nChannels)); } if (pInfo->wBitsPerSample) { Infos.AddTail(FormatString(L"%d bit", pInfo->wBitsPerSample)); } if (pInfo->nAvgBytesPerSec) { Infos.AddTail(FormatBitrate(pInfo->nAvgBytesPerSec * 8)); } } else if (pmt->formattype == FORMAT_VorbisFormat) { const VORBISFORMAT *pInfo = GetFormatHelper(pInfo, pmt); Infos.AddTail(CMediaTypeEx::GetAudioCodecName(pmt->subtype, 0)); if (pInfo->nSamplesPerSec) { Infos.AddTail(FormatString(L"%.1f kHz", double(pInfo->nSamplesPerSec)/1000.0)); } if (pInfo->nChannels) { Infos.AddTail(FormatString(L"%d chn", pInfo->nChannels)); } if (pInfo->nAvgBitsPerSec) { Infos.AddTail(FormatString(L"%d bit", pInfo->nAvgBitsPerSec)); } if (pInfo->nAvgBitsPerSec) { Infos.AddTail(FormatBitrate(pInfo->nAvgBitsPerSec * 8)); } } else if (pmt->formattype == FORMAT_VorbisFormat2) { const VORBISFORMAT2 *pInfo = GetFormatHelper(pInfo, pmt); Infos.AddTail(CMediaTypeEx::GetAudioCodecName(pmt->subtype, 0)); if (pInfo->SamplesPerSec) { Infos.AddTail(FormatString(L"%.1f kHz", double(pInfo->SamplesPerSec)/1000.0)); } if (pInfo->Channels) { Infos.AddTail(FormatString(L"%d chn", pInfo->Channels)); } } } if (!Infos.IsEmpty()) { CString Ret = pName; Ret += " ("; bool bFirst = true; for (POSITION pos = Infos.GetHeadPosition(); pos; Infos.GetNext(pos)) { const CString& String = Infos.GetAt(pos); if (bFirst) { Ret += String; } else { Ret += L", " + String; } bFirst = false; } Ret += ')'; return Ret; } return pName; }
CString CMediaTypeEx::ToString(IPin* pPin) { CString packing, type, codec, dim, rate, dur; // TODO if (majortype == MEDIATYPE_DVD_ENCRYPTED_PACK) { packing = _T("Encrypted MPEG2 Pack"); } else if (majortype == MEDIATYPE_MPEG2_PACK) { packing = _T("MPEG2 Pack"); } else if (majortype == MEDIATYPE_MPEG2_PES) { packing = _T("MPEG2 PES"); } if (majortype == MEDIATYPE_Video) { type = _T("Video"); BITMAPINFOHEADER bih; bool fBIH = ExtractBIH(this, &bih); int w, h, arx, ary; bool fDim = ExtractDim(this, w, h, arx, ary); if (fBIH) { codec = GetVideoCodecName(subtype, bih.biCompression); } if (codec.IsEmpty()) { if (formattype == FORMAT_MPEGVideo) { codec = _T("MPEG1 Video"); } else if (formattype == FORMAT_MPEG2_VIDEO) { codec = _T("MPEG2 Video"); } else if (formattype == FORMAT_DiracVideoInfo) { codec = _T("Dirac Video"); } } if (fDim) { dim.Format(_T("%dx%d"), w, h); if (w*ary != h*arx) { dim.AppendFormat(_T(" (%d:%d)"), arx, ary); } } if (formattype == FORMAT_VideoInfo || formattype == FORMAT_MPEGVideo) { VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)pbFormat; if (vih->AvgTimePerFrame) { rate.Format(_T("%0.3f"), 10000000.0f / vih->AvgTimePerFrame); rate.TrimRight(_T('0')); // remove trailing zeros rate.TrimRight(_T('.')); // remove the trailing dot rate += _T("fps "); } if (vih->dwBitRate) { rate.AppendFormat(_T("%dkbps"), vih->dwBitRate/1000); } } else if (formattype == FORMAT_VideoInfo2 || formattype == FORMAT_MPEG2_VIDEO || formattype == FORMAT_DiracVideoInfo) { VIDEOINFOHEADER2* vih = (VIDEOINFOHEADER2*)pbFormat; if (vih->AvgTimePerFrame) { rate.Format(_T("%0.3f"), 10000000.0f / vih->AvgTimePerFrame); rate.TrimRight(_T('0')); // remove trailing zeros rate.TrimRight(_T('.')); // remove the trailing dot rate += _T("fps "); } if (vih->dwBitRate) { rate.AppendFormat(_T("%dkbps"), vih->dwBitRate/1000); } } rate.TrimRight(); if (subtype == MEDIASUBTYPE_DVD_SUBPICTURE) { type = _T("Subtitle"); codec = _T("DVD Subpicture"); } } else if (majortype == MEDIATYPE_Audio) { type = _T("Audio"); if (formattype == FORMAT_WaveFormatEx) { WAVEFORMATEX* wfe = (WAVEFORMATEX*)Format(); if (wfe->wFormatTag/* > WAVE_FORMAT_PCM && wfe->wFormatTag < WAVE_FORMAT_EXTENSIBLE && wfe->wFormatTag != WAVE_FORMAT_IEEE_FLOAT*/ || subtype != GUID_NULL) { codec = GetAudioCodecName(subtype, wfe->wFormatTag); dim.Format(_T("%dHz"), wfe->nSamplesPerSec); if (wfe->nChannels == 1) { dim += _T(" mono"); } else if (wfe->nChannels == 2) { dim += _T(" stereo"); } else { dim.AppendFormat(_T(" %dch"), wfe->nChannels); } if (wfe->nAvgBytesPerSec) { rate.Format(_T("%dkbps"), wfe->nAvgBytesPerSec*8/1000); } } } else if (formattype == FORMAT_VorbisFormat) { VORBISFORMAT* vf = (VORBISFORMAT*)Format(); codec = GetAudioCodecName(subtype, 0); dim.Format(_T("%dHz"), vf->nSamplesPerSec); if (vf->nChannels == 1) { dim += _T(" mono"); } else if (vf->nChannels == 2) { dim += _T(" stereo"); } else { dim.AppendFormat(_T(" %dch"), vf->nChannels); } if (vf->nAvgBitsPerSec) { rate.Format(_T("%dkbps"), vf->nAvgBitsPerSec/1000); } } else if (formattype == FORMAT_VorbisFormat2) { VORBISFORMAT2* vf = (VORBISFORMAT2*)Format(); codec = GetAudioCodecName(subtype, 0); dim.Format(_T("%dHz"), vf->SamplesPerSec); if (vf->Channels == 1) { dim += _T(" mono"); } else if (vf->Channels == 2) { dim += _T(" stereo"); } else { dim.AppendFormat(_T(" %dch"), vf->Channels); } } } else if (majortype == MEDIATYPE_Text) { type = _T("Text"); } else if (majortype == MEDIATYPE_Subtitle) { type = _T("Subtitle"); codec = GetSubtitleCodecName(subtype); } else { type = _T("Unknown"); } if (CComQIPtr<IMediaSeeking> pMS = pPin) { REFERENCE_TIME rtDur = 0; if (SUCCEEDED(pMS->GetDuration(&rtDur)) && rtDur) { rtDur /= 10000000; int s = rtDur%60; rtDur /= 60; int m = rtDur%60; rtDur /= 60; int h = (int)rtDur; if (h) { dur.Format(_T("%d:%02d:%02d"), h, m, s); } else if (m) { dur.Format(_T("%02d:%02d"), m, s); } else if (s) { dur.Format(_T("%ds"), s); } } } CString str; if (!codec.IsEmpty()) { str += codec + _T(" "); } if (!dim.IsEmpty()) { str += dim + _T(" "); } if (!rate.IsEmpty()) { str += rate + _T(" "); } if (!dur.IsEmpty()) { str += dur + _T(" "); } str.Trim(_T(" ,")); if (!str.IsEmpty()) { str = type + _T(": ") + str; } else { str = type; } return str; }
static void SetupMediaTypes(IAMStreamConfig* pAMSC, CFormatArray<T>& tfa, CComboBox& type, CComboBox& dim, CMediaType& mt) { tfa.RemoveAll(); type.ResetContent(); dim.ResetContent(); type.EnableWindow(FALSE); dim.EnableWindow(FALSE); if (!pAMSC) { return; } AM_MEDIA_TYPE* pcurmt = NULL; pAMSC->GetFormat(&pcurmt); int iCount = 0, iSize; if (SUCCEEDED(pAMSC->GetNumberOfCapabilities(&iCount, &iSize)) && iSize == sizeof(T) && iCount > 0) { for (int i = 0; i < iCount; i++) { T caps; AM_MEDIA_TYPE* pmt = NULL; if (SUCCEEDED(pAMSC->GetStreamCaps(i, &pmt, (BYTE*)&caps))) { tfa.AddFormat(pmt, caps); } } if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS)) { for (int i = 0, cnt = tfa.GetCount(); i < cnt; i++) { if (tfa[i]->GetCount() != 1) { continue; } CFormatElem<T>* pfe = tfa[i]->GetAt(0); if (pfe->mt.formattype != FORMAT_VideoInfo && pfe->mt.formattype != FORMAT_VideoInfo2) { continue; } static SIZE presets[] = { {160, 120}, {192, 144}, {320, 240}, {384, 288}, {480, 240}, {512, 288}, {480, 360}, {512, 384}, {640, 240}, {768, 288}, {640, 480}, {768, 576}, {704, 240}, {704, 288}, {704, 480}, {704, 576}, {720, 240}, {720, 288}, {720, 480}, {720, 576}, {768, 240}, {768, 288}, {768, 480}, {768, 576}, }; VIDEO_STREAM_CONFIG_CAPS* pcaps = (VIDEO_STREAM_CONFIG_CAPS*)&pfe->caps; BITMAPINFOHEADER bihCur; ExtractBIH(&pfe->mt, &bihCur); for (int j = 0; j < countof(presets); j++) { if (presets[j].cx == bihCur.biWidth && presets[j].cy == abs(bihCur.biHeight) || presets[j].cx < pcaps->MinOutputSize.cx || presets[j].cx > pcaps->MaxOutputSize.cx || presets[j].cy < pcaps->MinOutputSize.cy || presets[j].cy > pcaps->MaxOutputSize.cy || presets[j].cx % pcaps->OutputGranularityX || presets[j].cy % pcaps->OutputGranularityY) { continue; } CMediaType mt = pfe->mt; if (mt.formattype == FORMAT_VideoInfo) { VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)mt.pbFormat; if (!vih->bmiHeader.biHeight) { vih->bmiHeader.biHeight = 1; } vih->bmiHeader.biWidth = presets[j].cx; vih->bmiHeader.biHeight = presets[j].cy*(vih->bmiHeader.biHeight/vih->bmiHeader.biHeight); vih->bmiHeader.biSizeImage = presets[j].cx*presets[j].cy*vih->bmiHeader.biBitCount>>3; AM_MEDIA_TYPE* pmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); CopyMediaType(pmt, &mt); tfa.AddFormat(pmt, pcaps, sizeof(*pcaps)); if (presets[j].cx*3 != presets[j].cy*4) { int extra = mt.cbFormat - sizeof(VIDEOINFOHEADER); int bmiHeaderSize = sizeof(vih->bmiHeader) + extra; BYTE* pbmiHeader = DNew BYTE[bmiHeaderSize]; memcpy(pbmiHeader, &vih->bmiHeader, bmiHeaderSize); mt.ReallocFormatBuffer(FIELD_OFFSET(VIDEOINFOHEADER2, bmiHeader) + bmiHeaderSize); VIDEOINFOHEADER2* vih2 = (VIDEOINFOHEADER2*)mt.pbFormat; memcpy(&vih2->bmiHeader, pbmiHeader, bmiHeaderSize); delete [] pbmiHeader; vih2->dwInterlaceFlags = vih2->dwCopyProtectFlags = 0; vih2->dwReserved1 = vih2->dwReserved2 = 0; vih2->dwPictAspectRatioX = 4; vih2->dwPictAspectRatioY = 3; AM_MEDIA_TYPE* pmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); CopyMediaType(pmt, &mt); tfa.AddFormat(pmt, pcaps, sizeof(*pcaps)); } } else if (mt.formattype == FORMAT_VideoInfo2) { VIDEOINFOHEADER2* vih2 = (VIDEOINFOHEADER2*)mt.pbFormat; if (!vih2->bmiHeader.biHeight) { vih2->bmiHeader.biHeight = 1; } vih2->bmiHeader.biWidth = presets[j].cx; vih2->bmiHeader.biHeight = presets[j].cy*(vih2->bmiHeader.biHeight/vih2->bmiHeader.biHeight); vih2->bmiHeader.biSizeImage = presets[j].cx*presets[j].cy*vih2->bmiHeader.biBitCount>>3; vih2->dwPictAspectRatioX = 4; vih2->dwPictAspectRatioY = 3; AM_MEDIA_TYPE* pmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); CopyMediaType(pmt, &mt); tfa.AddFormat(pmt, pcaps, sizeof(*pcaps)); } } }
STDMETHODIMP TffdshowVideoInputPin::ReceiveConnection(IPin* pConnector, const AM_MEDIA_TYPE* pmt) { HRESULT hr; DPRINTF(_l("TffdshowVideoInputPin::ReceiveConnection")); CAutoLock cObjectLock(m_pLock); const CLSID &ref = GetCLSID(pConnector); if (ref == CLSID_MPC_MatroskaSplitter || ref == CLSID_GabestMatroskaSplitter) { connectedSplitter = MPC_matroska_splitter; } else if (ref == CLSID_HaaliMediaSplitter) { connectedSplitter = Haali_Media_splitter; } else if (ref == CLSID_MPC_MpegSourceFilter || ref == CLSID_MPC_MpegSplitterFilter) { connectedSplitter = MPC_mpegSplitters; } else if (ref == CLSID_DVBSourceFilter) { connectedSplitter = DVBSourceFilter; } else if (ref == CLSID_PBDA_DTFilter) { connectedSplitter = PBDA_DTFilter; } else if (ref == CLSID_NeuviewSource) { connectedSplitter = NeuviewSource; } #if 0 PIN_INFO pininfo; FILTER_INFO filterinfo; pConnector->QueryPinInfo(&pininfo); if (pininfo.pFilter) { pininfo.pFilter->QueryFilterInfo(&filterinfo); DPRINTF(_l("TffdshowVideoInputPin::ReceiveConnection filter=%s pin=%s"), filterinfo.achName, pininfo.achName); if (filterinfo.pGraph) { filterinfo.pGraph->Release(); } pininfo.pFilter->Release(); } DPRINTF(_l("CLSID 0x%x,0x%x,0x%x"), ref.Data1, ref.Data2, ref.Data3); for (int i = 0; i < 8; i++) { DPRINTF(_l(",0x%2x"), ref.Data4[i]); } #endif if (m_Connected) { CMediaType mt(*pmt); BITMAPINFOHEADER bih, bihCur; ExtractBIH(mt, &bih); ExtractBIH(m_mt, &bihCur); // HACK: for the intervideo filter, when it tries to change the pitch from 720 to 704... //if(bihCur.biWidth != bih.biWidth && bihCur.biHeight == bih.biHeight) // return S_OK; return (CheckMediaType(&mt) != S_OK || SetMediaType(&mt) != S_OK/* || !initVideo(mt)*/) ? VFW_E_TYPE_NOT_ACCEPTED : S_OK; // TODO: send ReceiveConnection downstream } else { hr = fv->deci->checkInputConnect(pConnector); if (hr != S_OK) { return hr; } } hr = TinputPin::ReceiveConnection(pConnector, pmt); return hr; }
//------------------------------- decompress ------------------------------- bool TvideoCodecUncompressed::beginDecompress(TffPictBase &pict,FOURCC infcc,const CMediaType &mt,int sourceFlags) { switch (codecId) { case CODEC_ID_YV12: csp=FF_CSP_420P|FF_CSP_FLAGS_YUV_ADJ; break; case CODEC_ID_I420: csp=FF_CSP_420P|FF_CSP_FLAGS_YUV_ADJ|FF_CSP_FLAGS_YUV_ORDER; break; case CODEC_ID_YUY2: csp=FF_CSP_YUY2; break; case CODEC_ID_YVYU: csp=FF_CSP_YVYU; break; case CODEC_ID_UYVY: csp=FF_CSP_UYVY; break; case CODEC_ID_VYUY: csp=FF_CSP_VYUY; break; case CODEC_ID_RGB2: csp=FF_CSP_RGB24|FF_CSP_FLAGS_VFLIP; break; case CODEC_ID_RGB3: csp=FF_CSP_RGB32|FF_CSP_FLAGS_VFLIP; break; case CODEC_ID_RGB5: csp=FF_CSP_RGB15|FF_CSP_FLAGS_VFLIP; break; case CODEC_ID_RGB6: csp=FF_CSP_RGB16|FF_CSP_FLAGS_VFLIP; break; case CODEC_ID_BGR2: csp=FF_CSP_BGR24; break; case CODEC_ID_BGR3: csp=FF_CSP_BGR32; break; case CODEC_ID_BGR5: csp=FF_CSP_BGR15; break; case CODEC_ID_BGR6: csp=FF_CSP_BGR16; break; case CODEC_ID_CLJR: csp=FF_CSP_CLJR; break; case CODEC_ID_444P: csp=FF_CSP_444P; break; case CODEC_ID_422P: csp=FF_CSP_422P; break; case CODEC_ID_411P: csp=FF_CSP_411P; break; case CODEC_ID_410P: csp=FF_CSP_410P; break; case CODEC_ID_Y800: csp=FF_CSP_Y800; break; case CODEC_ID_NV12: csp=FF_CSP_NV12|FF_CSP_FLAGS_YUV_ADJ; break; case CODEC_ID_YV16: csp=FF_CSP_422P|FF_CSP_FLAGS_YUV_ADJ; break; default: return false; } cspInfo=csp_getInfo(pict.csp=csp); if (csp_isRGB(csp)) { stride[0]=ffalign(pict.rectFull.dx*cspInfo->Bpp<<3, 32)>>3; BITMAPINFOHEADER bih; ExtractBIH(mt,&bih); if (bih.biHeight < 0) { csp &= ~FF_CSP_FLAGS_VFLIP; } } else {