DirectShow->D3D как можно быстрее
От: ov  
Дата: 13.11.06 16:43
Оценка:
всем привет
есть граф, обрабатывающий MPEG-2 файл в HD (1920x1080)
результат загоняется в d3d surface для последующего отображения в программе.
проблема в том, что это съедает почти все процессорное время и приводит к серьезным тормозам

делаю так: при получении семпла в потоке фильтра беру из собственного кеша готовую d3d surface, делаю ей lock, кладу в нее данные из семпла, делаю unlock и ставлю в очередь. данные я получаю в формате YUV, т.е. два байта на пиксель. поверхность создана соответствующая.

в основном потоке я беру эту поверхность из очереди, на pixel shader'ах перевожу в rgb, разбиваю на поля и рисую эти поля с нужными коэффициентами прозрачности на экран в нужном месте. поверхность возвращаю в кеш.

вроде бы, оптимальнее уже сложно что-то придумать, только если как-то избавиться от lock'а этих поверхностей вообще и каким-то образом сказать декодеру, чтобы он клал данные сразу в surface. что-то подобное можно сделать через vmr9, но по тестам это дает прирост всего в 5%, да и то — тестовая программа значительно проще нашей, поэтому, возможно, прироста и не будет вовсе.

решал ли кто-нибудь такие задачи? может есть более шустрый способ?
Re: DirectShow->D3D как можно быстрее
От: Edge  
Дата: 14.11.06 08:55
Оценка:
Здравствуйте, ov, Вы писали:

ov>есть граф, обрабатывающий MPEG-2 файл в HD (1920x1080)

ov>результат загоняется в d3d surface для последующего отображения в программе.
ov>проблема в том, что это съедает почти все процессорное время и приводит к серьезным тормозам

ov>делаю так: при получении семпла в потоке фильтра беру из собственного кеша готовую d3d surface, делаю ей lock, кладу в нее данные из семпла, делаю unlock и ставлю в очередь. данные я получаю в формате YUV, т.е. два байта на пиксель. поверхность создана соответствующая.


ov>в основном потоке я беру эту поверхность из очереди, на pixel shader'ах перевожу в rgb, разбиваю на поля и рисую эти поля с нужными коэффициентами прозрачности на экран в нужном месте. поверхность возвращаю в кеш.


Вы не смотрели профайлером когда съедается время? случайно не при копировании семплов на поверхность? если так, то может быть причина в том, что вы заставляете процессор копировать из оперативной памяти в видеопамять, а такое копирование как правило _очень_ медленное. Для решения трабла вам каким-то образом надо сделать так, чтобы видеокарта сама засасывала из оперативной памяти данные. Возможно это можно сделать через D3D функции, представив семпл как текстуру, которую нужно подгрузить в видепамять — вполне возможно что видеокарта будет это делать через свои DMA механизмы.
Re: DirectShow->D3D как можно быстрее
От: Flay  
Дата: 14.11.06 14:03
Оценка:
ov>решал ли кто-нибудь такие задачи? может есть более шустрый способ?

Делай свой рендерер, ставь ему PREFERRED FORMAT как RGB, и, возможно
получиться в свой аллокатор подсунуть поинтер от поверхности D3D.

Тогда всё будет быстрее некуда.
Это в теории, на практике не пробовал, но вроде бы реализуемо.
Re[2]: DirectShow->D3D как можно быстрее
От: ov  
Дата: 14.11.06 17:00
Оценка:
ov>>решал ли кто-нибудь такие задачи? может есть более шустрый способ?
F>Делай свой рендерер, ставь ему PREFERRED FORMAT как RGB, и, возможно
F>получиться в свой аллокатор подсунуть поинтер от поверхности D3D.
если поставить свой формат RGB, а не YUV, то в граф добавится Color Converter, что скорости не прибавит
на выходе будет минимум в 1.5 раза больше инфы, а если в RGBA, то в 2 раза больше.

F>Тогда всё будет быстрее некуда.

да не факт. с RGB точно медленнее будет. в YUV 2 байта на пиксел, меньше некуда, конвертация на шейдерах — быстрее способа нет.

F>Это в теории, на практике не пробовал, но вроде бы реализуемо.

а на практике-то все, как раз, фигово...
Re[2]: DirectShow->D3D как можно быстрее
От: ov  
Дата: 14.11.06 17:02
Оценка:
E>Вы не смотрели профайлером когда съедается время? случайно не при копировании семплов на поверхность? если так, то может быть причина в том, что вы заставляете процессор копировать из оперативной памяти в видеопамять, а такое копирование как правило _очень_ медленное. Для решения трабла вам каким-то образом надо сделать так, чтобы видеокарта сама засасывала из оперативной памяти данные. Возможно это можно сделать через D3D функции, представив семпл как текстуру, которую нужно подгрузить в видепамять — вполне возможно что видеокарта будет это делать через свои DMA механизмы.

проблема в том, что Lock поверхности возвращает адрес.
и в IMediaSample тоже приходит адрес. и по-любому надо копировать.
если залочить поверхность заранее и постараться подать ее декодеру, то возможны варианты, что он ее не возьмет и будет юзать свой аллокатор, а возможны варианты, что начнет глючить D3D и придется ставить безопасный многопоточный режим в нем, что съест скорость.

я вот сейчас как раз пытаюсь найти какой-то способ заставить видеокарту засасывать ресурсы самостоятельно, но что-то слабо верится в то, что это реально...
Re[3]: DirectShow->D3D как можно быстрее
От: Flay  
Дата: 14.11.06 20:26
Оценка:
ov>если поставить свой формат RGB, а не YUV, то в граф добавится Color Converter, что скорости не прибавит

Ясен перец, что Color Converter убьёт всю идею на корню.
Попробуй разные RGB-space, а лучше посмотри на выходе декодера, какие типы он поддерживает.
Если RGB совсем не поддерживает, тогда труба. Может другой декодер поискать?

ov>на выходе будет минимум в 1.5 раза больше инфы, а если в RGBA, то в 2 раза больше.


Как это скажется на скорости, покажет эксперимент.
Видео-карты — они такие хитрые внутри...
Re[3]: DirectShow->D3D как можно быстрее
От: Front Россия  
Дата: 15.11.06 08:11
Оценка:
ov>если поставить свой формат RGB, а не YUV, то в граф добавится Color Converter
Виталий, чтобы не добавлялся CSC нужно написать свой рендерер, который при проверке медиаформатов будет не по-байтно их сравнивать, а только значимые поля. Свой аллокатор на входном пине поможет избавиться от копирования данных из семплов в поверхность.

ov>на выходе будет минимум в 1.5 раза больше инфы, а если в RGBA, то в 2 раза больше.

Использование YUV — это не решение проблемы, так как рано или поздно понадобится и альфа.
Front
Re: DirectShow->D3D как можно быстрее
От: Аноним  
Дата: 15.11.06 08:15
Оценка:
ov>делаю так: при получении семпла в потоке фильтра беру из собственного кеша готовую d3d surface
Как решаете проблему синхронного получение семплов для видеотекстуры и асинхронности рендеринга основной сцены?
Re[3]: DirectShow->D3D как можно быстрее
От: Sapersky  
Дата: 15.11.06 14:18
Оценка:
Здравствуйте, ov, Вы писали:

ov>я вот сейчас как раз пытаюсь найти какой-то способ заставить видеокарту засасывать ресурсы самостоятельно, но что-то слабо верится в то, что это реально...


Вот мелкософт предлагает:
"For dynamic textures, it is sometimes desirable to use a pair of video memory and system memory textures, allocating the video memory using D3DPOOL_DEFAULT and the system memory using D3DPOOL_SYSTEMMEM. You can lock and modify the bits of the system memory texture using a locking method. Then you can update the video memory texture using IDirect3DDevice8::UpdateTexture."
Re[4]: DirectShow->D3D как можно быстрее
От: Alglib Россия  
Дата: 16.11.06 21:25
Оценка:
F>Ясен перец, что Color Converter убьёт всю идею на корню.
F>Попробуй разные RGB-space, а лучше посмотри на выходе декодера, какие типы он поддерживает.
F>Если RGB совсем не поддерживает, тогда труба. Может другой декодер поискать?

Извините, что влезаю, но какая в сущности разница где будет конвертация, внутри декодера или снаружи, если видео в потоке в YUV?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.