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


Совместное использование данных между потоками

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

Примечание

Эти API являются устаревшими. Приложения должны использовать фильтр Sample Grabber или реализовать пользовательский фильтр для получения данных из графа фильтра DirectShow.

 

Обработка мультимедийных данных обычно требует большого количества системных ресурсов; поэтому следует избегать копирования данных, когда это возможно. Архитектура потоковой передачи поддерживает примеры общих потоков— механизм, который перемещает данные из одного потока в другой без копирования. Этот буфер обеспечивает эффективную передачу данных между двумя потоками, даже если целевой поток не поддерживает базовый формат данных.

Например, предположим, что у вас есть мультимедийный поток с тремя потоками данных: видео и аудио, а также данные URL-адреса с меткой времени для соответствия видеосодержимого. Вы хотите написать приложение, которое добавляет уведомление об авторских правах на каждый видеокадр и записывает данные в другой поток для хранения, но ваше приложение не понимает форматы данных, кроме видеопотока. Для видеопотока создайте пример, подключенный к нужной поверхности DirectDraw. Затем можно создать выходной поток, вызвав метод IDirectDrawMediaStream::CreateSample с указателем на ту же поверхность или IMediaStream::CreateSharedSample. В обоих случаях входные и выходные потоки совместно используют поверхность DirectDraw. Так как вы понимаете формат видео, вы можете получить доступ к этой поверхности при необходимости.

Чтобы получить другие указатели исходного потока (аудио и URL-адрес), перечислите исходный поток контейнера и захватить указатели на невидео-потоки. Каждый из этих исходных потоков имеет связанный выходной поток в контейнере выходного потока. Получите эти выходные указатели, вызвав метод IMultiMediaStream::GetMediaStream в выходном контейнере с каждым из указателей исходного потока. Следующие шаги описывают данный процесс.

  1. Вызовите IMultiMediaStream::EnumMediaStreams , чтобы получить указатель на исходный поток. Убедитесь, что это не видеопоток, так как приложение уже понимает его формат.
  2. Вызовите IMultiMediaStream::GetMediaStream в потоке выходного контейнера с помощью указателя из шага 1. При этом возвращается указатель на нужный выходной поток.
  3. Вызовите Метод AllocateSample в исходном потоке.
  4. Вызовите CreateSharedSample в выходном потоке.
  5. Вызовите Update в исходном потоке для чтения данных.
  6. Вызовите Update в выходном потоке для записи данных.

Повторите эти действия для каждого потока, формат которого не поддерживается. Когда оба примера завершат обновление, выходной поток содержит все данные из исходного потока, и все готово.