Beispiel #1
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;
}
Beispiel #2
0
HRESULT CBaseVideoFilter::ReconnectOutput(int w, int h, bool bSendSample, int realWidth, int realHeight)
{
    CMediaType& mt = m_pOutput->CurrentMediaType();

    bool m_update_aspect = false;
    if (f_need_set_aspect) {
        int wout = 0, hout = 0, arxout = 0, aryout = 0;
        ExtractDim(&mt, wout, hout, arxout, aryout);
        if (arxout != m_arx || aryout != m_ary) {
            TRACE(_T("\nCBaseVideoFilter::ReconnectOutput; wout = %d, hout = %d, current = %dx%d, set = %dx%d\n"), wout, hout, arxout, aryout, m_arx, m_ary);
            m_update_aspect = true;
        }
    }

    int w_org = m_w;
    int h_org = m_h;

    bool fForceReconnection = false;
    if (w != m_w || h != m_h) {
        fForceReconnection = true;
        m_w = w;
        m_h = h;
    }

    HRESULT hr = S_OK;

    if (m_update_aspect || fForceReconnection || m_w != m_wout || m_h != m_hout || m_arx != m_arxout || m_ary != m_aryout) {
        if (GetCLSID(m_pOutput->GetConnected()) == CLSID_VideoRenderer) {
            NotifyEvent(EC_ERRORABORT, 0, 0);
            return E_FAIL;
        }

        BITMAPINFOHEADER* bmi = NULL;

        if (mt.formattype == FORMAT_VideoInfo) {
            VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)mt.Format();
            if (realWidth > 0 && realHeight > 0) {
                SetRect(&vih->rcSource, 0, 0, realWidth, realHeight);
                SetRect(&vih->rcTarget, 0, 0, realWidth, realHeight);
            } else {
                SetRect(&vih->rcSource, 0, 0, m_w, m_h);
                SetRect(&vih->rcTarget, 0, 0, m_w, m_h);
            }
            bmi = &vih->bmiHeader;
            bmi->biXPelsPerMeter = m_w * m_ary;
            bmi->biYPelsPerMeter = m_h * m_arx;
        } else if (mt.formattype == FORMAT_VideoInfo2) {
            VIDEOINFOHEADER2* vih = (VIDEOINFOHEADER2*)mt.Format();
            if (realWidth > 0 && realHeight > 0) {
                SetRect(&vih->rcSource, 0, 0, realWidth, realHeight);
                SetRect(&vih->rcTarget, 0, 0, realWidth, realHeight);
            } else {
                SetRect(&vih->rcSource, 0, 0, m_w, m_h);
                SetRect(&vih->rcTarget, 0, 0, m_w, m_h);
            }
            bmi = &vih->bmiHeader;
            vih->dwPictAspectRatioX = m_arx;
            vih->dwPictAspectRatioY = m_ary;
        } else {
            return E_FAIL;  //should never be here? prevent null pointer refs for bmi
        }

        bmi->biWidth = m_w;
        bmi->biHeight = m_h;
        bmi->biSizeImage = m_w * m_h * bmi->biBitCount >> 3;

        hr = m_pOutput->GetConnected()->QueryAccept(&mt);
        ASSERT(SUCCEEDED(hr)); // should better not fail, after all "mt" is the current media type, just with a different resolution
        HRESULT hr1 = 0;
        CComPtr<IMediaSample> pOut;
        if (SUCCEEDED(hr1 = m_pOutput->GetConnected()->ReceiveConnection(m_pOutput, &mt))) {
            if (bSendSample) {
                HRESULT hr2 = 0;
                if (SUCCEEDED(hr2 = m_pOutput->GetDeliveryBuffer(&pOut, NULL, NULL, 0))) {
                    AM_MEDIA_TYPE* pmt;
                    if (SUCCEEDED(pOut->GetMediaType(&pmt)) && pmt) {
                        CMediaType mt2 = *pmt;
                        m_pOutput->SetMediaType(&mt2);
                        DeleteMediaType(pmt);
                    } else { // stupid overlay mixer won't let us know the new pitch...
                        long size = pOut->GetSize();
                        bmi->biWidth = size ? (size / abs(bmi->biHeight) * 8 / bmi->biBitCount) : bmi->biWidth;
                    }
                } else {
                    m_w = w_org;
                    m_h = h_org;
                    return E_FAIL;
                }
            }
        }

        m_wout = m_w;
        m_hout = m_h;
        m_arxout = m_arx;
        m_aryout = m_ary;

        // some renderers don't send this
        NotifyEvent(EC_VIDEO_SIZE_CHANGED, MAKELPARAM(m_w, m_h), 0);

        return S_OK;
    }

    return S_FALSE;
}