Управление графом записи

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

Интерфейс IMediaControl диспетчера графа фильтров имеет методы запуска, остановки и приостановки всего графа. Однако если граф фильтров содержит потоки записи и предварительного просмотра, вероятно, требуется управлять двумя потоками независимо. Например, вы можете просмотреть видео без записи. Это можно сделать с помощью метода ICaptureGraphBuilder2::ControlStream.

Заметка

Этот метод не работает при записи в файл расширенного формата систем (ASF).

 

Управление потоком записи

Следующий код задает поток видеозахвата для выполнения в течение четырех секунд, начиная с одной секунды после выполнения графа:

// Control the video capture stream. 
REFERENCE_TIME rtStart = 10000000, rtStop = 50000000;
const WORD wStartCookie = 1, wStopCookie = 2;  // Arbitrary values.
hr = pBuild->ControlStream(
    &PIN_CATEGORY_CAPTURE, // Pin category.
    &MEDIATYPE_Video,      // Media type.
    pCap,                 // Capture filter.
    &rtStart, &rtStop,     // Start and stop times.
    wStartCookie, wStopCookie  // Values for the start and stop events.
);
pControl->Run();

Первый параметр указывает, какой поток следует контролировать, в качестве GUID категории контактов. Второй параметр предоставляет тип носителя. Третий параметр — указатель на фильтр записи. Чтобы управлять всеми потоками записи в графе, задайте для второго и третьего параметров значение NULL.

Следующие два параметра определяют время запуска и остановки потока относительно времени запуска графа. Вызовите IMediaControl::Run для запуска графа. До запуска графа метод ControlStream не действует. Если граф уже запущен, параметры вступают в силу немедленно.

Последние два параметра используются для получения уведомлений о событиях при запуске и остановке потока. Для каждого управляемого потока с помощью этого метода граф фильтра отправляет пару событий: EC_STREAM_CONTROL_STARTED при запуске потока и EC_STREAM_CONTROL_STOPPED при остановке потока. Значения wStartCookie и wStopCookie используются в качестве второго параметра события. Таким образом, lParam2 в начальном событии равно wStartCookie, а lParam2 в событии остановки равно wStopCookie. В следующем коде показано, как получить эти события:

while (hr = pEvent->GetEvent(&evCode, &param1, &param2, 0), SUCCEEDED(hr))
{
    switch (evCode)
    {
    case EC_STREAM_CONTROL_STARTED: 
    // param2 == wStartCookie
    break;

    case EC_STREAM_CONTROL_STOPPED: 
    // param2 == wStopCookie
    break;
    
    } 
    pEvent->FreeEventParams(evCode, param1, param2);
}

Метод ControlStream определяет некоторые специальные значения для времени начала и остановки.

Ценность Начало Остановка
MAXLONGLONG Никогда не запускайте этот поток. Не останавливаться до остановки графа.
NULL Начинайте одновременно с запуском графа. Немедленно остановите.

 

Например, следующий код немедленно останавливает поток записи:

pBuild->ControlStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pCap,
    0, 0,     // Start and stop times.
    wStartCookie, wStopCookie); 

Хотя вы можете остановить поток записи и перезапустить его позже, это создаст разрыв в метках времени. При воспроизведении видео будет останавливаться во время разрыва (в зависимости от формата файла).

Управление потоком предварительной версии

Чтобы управлять пином режима предварительного просмотра, вызовите ControlStream, но задайте для первого параметра значение PIN_CATEGORY_PREVIEW. Это работает так же, как и для PIN_CATEGORY_CAPTURE, за исключением того, что нельзя использовать время ссылки для указания времени начала и остановки, так как в кадрах предварительного просмотра нет меток времени. Поэтому необходимо использовать NULL или MAXLONGLONG. Используйте NULL для запуска потока предварительной версии:

pBuild->ControlStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pCap,
    NULL,    // Start now.
    0,       // (Don't care.)
    wStartCookie, wStopCookie); 

Чтобы остановить поток предварительного просмотра, используйте MAXLONGLONG.

pBuild->ControlStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pCap,
    0,               // (Don't care.)
    MAXLONGLONG,     // Stop now.
    wStartCookie, wStopCookie); 

Не имеет значения, поступает ли поток предварительного просмотра из значка предварительного просмотра в фильтре захвата или из фильтра Smart Tee. Метод ControlStream работает в любом случае.

Однако для выводов видеопорта метод не сработает. В этом случае другим подходом является скрытие окна видео. Выполните запрос графа для IVideoWindowи используйте метод IVideoWindow::put_Visible для отображения или скрытия окна.

// Hide the video window.
IVideoWindow *pVidWin = 0;
hr = pGraph->QueryInterface(IID_IVideoWindow, (void**)&pVidWin);
if (SUCCEEDED(hr))
{
    pVidWin->put_Visible(OAFALSE);
    pVidWin->Release();
}

Кроме того, если вы вызовете IVideoWindow::put_AutoShow со значением OAFALSE перед запуском графа, фильтр "Отрисовщик видео" будет скрывать окно, пока не укажете иначе. По умолчанию средство отрисовки видео отображает окно при запуске графа.

Примечания об элементе управления потоками

Поведение по умолчанию для пин-кода заключается в доставке примеров при выполнении графа. Например, предположим, что вы вызываете ControlStream с помощью PIN_CATEGORY_CAPTURE, но не используете PIN_CATEGORY_PREVIEW. При запуске графа поток предварительного просмотра будет выполняться немедленно, а поток записи будет выполняться в указанное вами время, указанное в ControlStream.

Если вы записываете несколько потоков и отправляете их в мультиплексорный фильтр, например, если вы записываете аудио и видео в AVI-файл, следует управлять обоими потоками в тандеме. В противном случае мультиплексор может блокировать ожидание одного из потоков, так как он пытается чередовать два потока. Задайте одно и то же время запуска и остановки во всех потоках записи перед запуском графа:

pBuild->ControlStream(&PIN_CATEGORY_CAPTURE, 
    
NULL, NULL,       // All capture streams.
    &rtStart, rtStop, 
    wStartCookie, wStopCookie); 

Метод ControlStream использует интерфейс IAMStreamControl, который предоставляется на контактах фильтра захвата, а также Smart Tee фильтра (если он присутствует) и, возможно, фильтра мультиплексора. Этот интерфейс можно использовать напрямую, а не вызывать ControlStream, хотя для этого нет особых преимуществ.

захват видео