Поделиться через


Реализация закрепления предварительного просмотра (необязательно)

[Функция, связанная с этой страницей DirectShow, является устаревшей функцией. Он был заменен MediaPlayer, IMFMediaEngine, и аудио/ видео захвата в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует использовать в новом коде MediaPlayer, IMFMediaEngine и аудио/видеозахват в Media Foundation вместо DirectShow, когда это возможно. Корпорация Майкрософт предлагает переписать существующий код, в котором используются устаревшие API, чтобы по возможности использовать новые API.]

В этом разделе описывается, как реализовать предварительную версию закрепления в фильтре записи DirectShow.

Если фильтр содержит пин-код предварительного просмотра, он должен отправить копию данных, доставленных маркером захвата. Отправка данных только из контакта предварительного просмотра при этом не приведет к удалению кадров. Закрепление захвата всегда имеет приоритет над контактом предварительного просмотра.

Пин-код записи и контакт предварительного просмотра должны отправлять данные в одном формате. Поэтому они должны подключаться с использованием идентичных типов носителей. Если контакт записи подключается первым, контакт предварительного просмотра должен предлагать тот же тип мультимедиа и отклонять любые другие типы. Если контакт предварительного просмотра подключается первым, а контакт захвата подключается к другому типу мультимедиа, контакт предварительного просмотра должен повторно подключиться с использованием нового типа мультимедиа. Если фильтр, нисходящий от контакта предварительного просмотра, отклоняет новый тип, контакт захвата также должен отклонять тип. Используйте метод IPin::QueryAccept для запроса нижестоящего фильтра из контакта предварительного просмотра и метод IFilterGraph::Reconnect для повторного подключения контакта. Эти правила также применяются, если диспетчер фильтров графов повторно подключает контакт захвата.

В следующем примере показана схема этого процесса:

// Override CBasePin::CheckMediaType.
CCapturePin::CheckMediaType(CMediaType *pmt)
{
    if (m_pMyPreviewPin->IsConnected()) 
    {
        // The preview pin is already connected, so query the pin it is
        // connected to. If the other pin rejects it, so do we.
        hr = m_pMyPreviewPin->GetConnected()->QueryAccept(pmt);
        if (hr != S_OK) 
        {
            // The preview pin cannot reconnect with this media type.
            return E_INVALIDARG;
        }
        // The preview pin will reconnect when SetMediaType is called.
    }
    // Decide whether the capture pin accepts the format. 
    BOOL fAcceptThisType = ...  // (Not shown.)
    return (fAcceptThisType? S_OK : E_FAIL);
}

// Override CBasePin::SetMediaType.
CCapturePin::SetMediaType(CMediaType *pmt);
{
    if (m_pMyPreviewPin->IsConnected()) 
    {
        // The preview pin is already connected, so it must reconnect.
        if (m_pMyPreviewPin->GetConnected()->QueryAccept(pmt) == S_OK)
        {
            // The downstream pin will accept the new type, so it's safe
            // to reconnect. 
            m_pFilter->m_pGraph->Reconnect(m_pMyPreviewPin);
        }
        else
        {
            return VFW_E_INVALIDMEDIATYPE;
        }
    }
    // Now do anything that the capture pin needs to set the type.
    hr = MyInternalSetMediaType(pmt);

    // And finally, call the base-class method.
    return CBasePin::SetMediaType(pmt);
}

CPreviewPin::CheckMediaType(CMediaType *pmt)
{
    if (m_pMyCapturePin->IsConnected())
    {
       // The preview pin must connect with the same type.
       CMediaType cmt = m_pMyCapturePin->m_mt;
       return (*pmt == cmt ? S_OK : VFW_E_INVALIDMEDIATYPE);
    }
    // Decide whether the preview pin accepts the format. You can use your 
    // knowledge of which types the capture pin will accept. Regardless,
    // when the capture pin connects, the preview pin will reconnect.
    return (fAcceptThisType? S_OK : E_FAIL);
}

Как подключить фильтры

Написание фильтров записи