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; }
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; }