2014-12-24 2 views
0

Недавно я работаю с 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.

+0

Непонятно, что именно делает 'GetSampleBufferOfMediaType', и что вы подразумеваете под« изображениями, которые неправильно отображались на экране ».Неясно, видите ли вы в любой момент новый тип медиа, прикрепленный к образцу СМИ. –

+0

@ RomanR. Я предполагаю, что MediaType соединения не изменился. – hxpax

ответ

0

Ваш раздел MSDN: QueryAccept (Downstream). Этот тип изменения формата работает только тогда, когда вы переключаетесь с более высокого разрешения на более низкое, то есть когда соединение не нуждается в повторном согласии с распределителем памяти, а уже выделенные буферы подходят для нового обновленного разрешения.

Вы должны увидеть код ошибки или отказа, возвращенный средством визуализации видео в одном из вызовов: IPin::QueryAccept, IMediaSample::SetMediaType или IMemInputPin::Receive.

Затем, чтобы добавить к этому, даже если вы измените разрешение, видеообъект может захотеть дополнительно изменить шаг, чтобы соответствовать требованиям к оборудованию. Это особенно относится к меньшим разрешениям, поскольку средство визуализации/аппаратного обеспечения видео хочет, чтобы шаг был выровнен с 16 байтами или более. Ваш запрос на установку разрешения 352x288, вероятно, немедленно приведет к изменению Handling Format Changes from the Video Renderer, чтобы согласиться с тем же разрешением, но с увеличенным шагом. Невозможно обработать этот сценарий, скорее всего, приведет к визуальному визуализированию изображения со сдвинутыми линиями.

+0

Кажется, что соединение установлено, в другом слове был принят MediaType I, установленный для CIF? И мои коды работают только для 720P и 1080P, только если нет изменений формата. – hxpax

+0

Вы провели отличные исследования, устраняя проблему, однако важные вещи все еще остаются без изменений. Прежде всего, вы хотите проверить, получаете ли вы запросы на изменение динамического формата от типов рендеринга и медиафайлов со средами, которые он устанавливает (а не вы); то во-вторых, вы хотите проверить эффективную топологию, соединения и типы медиа - расхождения там часто объясняют проблему. Вы объясняете, что делаете, и также важно, что вы ДЕЙСТВИТЕЛЬНО получаете. –