Недавно я работаю с VC и DirectShow, проблема в том, что изменения динамического формата не сработали для меня.Ошибка моего DirectShow при изменении динамического формата
Я настроил CBaseFilter как свой SouceFilter. Он получает, заполняет и доставляет MediaSample (образец для краткости) в нисходящий фильтр, который точно является VMR. SourceFilter получает образец через CBaseOutputPin :: GetDeliveryBuffer и доставляет образец через CBaseOutputPin :: Deliver.
По соображениям разрешение кадров может меняться в любое время. Поэтому при каждом изменении разрешения я добавляю новый MediaType с шириной и высотой в pbFormat bmiHeader.
По Ot MSDN Dynamic Format Changes, я написал коды, как показано ниже:
// YUV420 frame got
// now try to get Sample buffer
if(pvi.bmiHeader.biWidth != width || pvi.bmiHeader.biHeight != height){
// if resolution changed
// generate new MediaType with new resolution
SetMediaType(width, height);
if(S_OK == pRenderInPin->QueryAccept(&mediaType)){
// if the input Pin of render accept the new MediaType
if(pSourceFilter){
/*
* In function GetSampleBufferOfMediaType,
* I ask for a Sample, attach a MediaType to it,
* and get its buffer for future use
*/
while(S_OK != pSourceFilter->GetSampleBufferOfMediaType(&mediaType, &pSampleBuffer)
&& isActive){
Sleep(8);
}
}
}else{
DEBUG_INFO("ERROR - failed on QueryAccept\n");
}
}else{
// in function GetSampleBuffer, just ask for a Sample buffer
while (S_OK != pSourceFilter->GetSampleBuffer(&pSampleBuffer)
&& isActive){
Sleep(8);
}
}
// fill buffer and deliver it
Я считал, что когда-то RenderFilter получить образец с новым MEDIATYPE прилагается, он будет вызывать IMediaSample :: GetMediaType, и принять новый MEDIATYPE. Но я обнаружил, что разрешение onece изменилось, GetSampleBufferOfMediaType будет выполняться, к сожалению, изображения не отображаются должным образом на экране.
Интересно, почему он не работает, как я и ожидал, и как мне изменить свою программу.
Подсказка будет высоко оценена.
----- [Дополнительные сведения] -----
В состоянии, которое не имеет каких-либо изменений в формате, мой MediaType работает с разрешением 720P и 1080P хорошо, но это не так повезло с CIF (352 * 288). Может быть, что-то не так с моей функцией SetMediaType()?
void CReadBufController::SetMediaType(short _width, short _height){
mMediaType.subtype = MEDIASUBTYPE_YV12;
mMediaType.majortype = MEDIATYPE_Video;
mMediaType.formattype = FORMAT_VideoInfo;
mMediaType.bFixedSizeSamples = FALSE;
mMediaType.bTemporalCompression = TRUE;
mMediaType.lSampleSize = 0;
mMediaType.pUnk = 0;
mMediaType.cbFormat = sizeof(VIDEOINFOHEADER);
pvi.bmiHeader.biBitCount = 12;
pvi.bmiHeader.biWidth = _width;
pvi.bmiHeader.biHeight = _height;
pvi.bmiHeader.biSizeImage = GetBitmapSize(&pvi.bmiHeader);
pvi.bmiHeader.biPlanes = 1;
pvi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pvi.bmiHeader.biCompression = MAKEFOURCC('Y', 'V', '1', '2');
mMediaType.pbFormat = (BYTE *)(&pvi);
}
----- [UPDATE] -----
Согласно комментарию @Roman_R, вот мой код GetSampleBufferOfMediaType:
// here CReadBufferFilter is the SourceFilter I mentioned
HRESULT CReadBufferFilter::GetSampleBufferOfMediaType(AM_MEDIA_TYPE *_pMediaType, PBYTE *_pBuffer){
SAFE_RELEASE(mSample);
// get a Sample from output Pin
mOutputPin->GetDeliveryBuffer(&mSample, NULL, NULL, 0);
// attach the new MediaType to the Sample
if(mSample && (S_OK == mSample->SetMediaType(_pMediaType))){
mSample->GetPointer(_pBuffer); // get the Sample buffer
return S_OK;
}
return E_FAIL;
}
«картины не правильно показать на экране "означает его серый цвет и перекрывается с его множественной копией изображения, просто действуйте так, как если бы вы назначили неправильную ширину и высоту для MediaType.
Непонятно, что именно делает 'GetSampleBufferOfMediaType', и что вы подразумеваете под« изображениями, которые неправильно отображались на экране ».Неясно, видите ли вы в любой момент новый тип медиа, прикрепленный к образцу СМИ. –
@ RomanR. Я предполагаю, что MediaType соединения не изменился. – hxpax