예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
            }
        }
    }
예제 #4
0
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;
}
예제 #6
0
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;
}
예제 #7
0
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));
					}
				}
			}
예제 #8
0
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 {