DirectX Графика в проектах Delphi

       

Модуль DirectShow



Поскольку изложенный в предыдущем разделе способ годится не для каждого видео, нам придется бегло рассмотреть еще один способ воспроизведения видео, основанный на использовании модуля DirectShow. Эта библиотека также входит в состав DirectX, включает набор функций для работы с мультимедиа. Подробно рассматривать ее не будем, познакомимся с ее использованием на конкретном примере, проекте каталога Ех02, воспроизводящем AVI-файл на поверхности (рис. 6.2).

Рис. 6.2. Работа примера на тему использования модуля DirectShow

Файл видео для этого примера также взят мною из пакета DirectX SDK.
При воспроизведении файла с помощью модуля VFW картинка получается искаженной, поэтому и приходится прибегать к иному способу. Отказаться от первого способа мы также не можем, поскольку DirectShow тоже годится не для любого файла. Другая причина, по которой мы не можем усердствовать в изучении упомянутого модуля, состоит в том, что он может применяться лишь с интерфейсами ранних версий.
Модуль использует СОМ-модель, поэтому здесь мы встретим знакомые понятия главного объекта и дочерних интерфейсов:

var
AMStream : lAMMultiMediaStream; // Главный объект
PrimaryVidStream : IMediaStream; // Дочерний поток, связан с видео
Sample : IDirectDrawStreamSample; // Интерфейс для вывода на поверхность

В процедуру инициализации потока передается имя требуемого файла:

procedure TfrmDD.PlayMedia(const FileName: WideString);
var
hRet : HRESULT;
begin
// Создание главного объекта ('filter graph1)
AMStream:=IAMMultiMediaStream(CreateComObject
(CLSID_AMMultiMediaStream));
// Инициализация потока для чтения
hRet := AMStream.Initialize(STREAMTYPE_READ, 0, nil);
if Failed (hRet) then ErrorOut (hRet, 'Stream Initialize');
// Добавление потока видео к главному объекту
hRet := AMStream.AddMediaStream(FDD, MSPID_PrimaryVideo,
0, IMediaStream(ni!A));
if Failed (hRet) then ErrorOut (hRet, 'Add Video Stream');
// Открытие файла
hRet := AMStream.OpenFile(PWideChar(FileName) , 0);
if Failed (hRet) then ErrorOut (hRet, 'Open AVI File');
// Следующие действия предназначены для связывания потока и поверхности
// Получение дочернего потока
hRet := (AMStream as IMultiMediaStream).
GetMediaStream(MSPID_PrimaryVideo, PrimaryVidStream);
if Failed (hRet) then ErrorOut (hRet, 'GetMediaStream');
// Преобразование интерфейса в тип Isample
//и связывание его с поверхностью
hRet := (PrimaryVidStream as IDirectDrawMediaStream).
CreateSample (FDDS Image, TRect(nil/4), 0, Sample);
if Failed (hRet) then ErrorOut (hRet, 'CreateSample');
// Запуск потока
hRet := (AMStream as IMultiMediaStream).SetState(STREAMSTATE_RUN);
if Failed (hRet) then ErrorOut (hRet, 'SetState');
end;

Обработку возможных ошибок я оставил прежней, но коды ошибок не будут расшифровываться. Модуль DirectDraw не содержит, конечно, пояснения по этим ошибкам.
Перед блиттингом поверхности FDDS image обновляем позицию в видео:

if Sample.Update(0, 0, nil, 0) <> S_OK
then (AMStream as IMultiMediaStream).Seek (0);

Неудача свидетельствует о том, что видео прокручено до конца, в этом случае мы заново запускаем его.
Самостоятельно разберитесь, каким образом останавливается ролик при деактивизации окна приложения, и как заново запускается поток при восстановлении.



Содержание раздела