всем привет
есть граф, обрабатывающий MPEG-2 файл в HD (1920x1080)
результат загоняется в d3d surface для последующего отображения в программе.
проблема в том, что это съедает почти все процессорное время и приводит к серьезным тормозам
делаю так: при получении семпла в потоке фильтра беру из собственного кеша готовую d3d surface, делаю ей lock, кладу в нее данные из семпла, делаю unlock и ставлю в очередь. данные я получаю в формате YUV, т.е. два байта на пиксель. поверхность создана соответствующая.
в основном потоке я беру эту поверхность из очереди, на pixel shader'ах перевожу в rgb, разбиваю на поля и рисую эти поля с нужными коэффициентами прозрачности на экран в нужном месте. поверхность возвращаю в кеш.
вроде бы, оптимальнее уже сложно что-то придумать, только если как-то избавиться от lock'а этих поверхностей вообще и каким-то образом сказать декодеру, чтобы он клал данные сразу в surface. что-то подобное можно сделать через vmr9, но по тестам это дает прирост всего в 5%, да и то — тестовая программа значительно проще нашей, поэтому, возможно, прироста и не будет вовсе.
решал ли кто-нибудь такие задачи? может есть более шустрый способ?
Здравствуйте, ov, Вы писали:
ov>есть граф, обрабатывающий MPEG-2 файл в HD (1920x1080) ov>результат загоняется в d3d surface для последующего отображения в программе. ov>проблема в том, что это съедает почти все процессорное время и приводит к серьезным тормозам
ov>делаю так: при получении семпла в потоке фильтра беру из собственного кеша готовую d3d surface, делаю ей lock, кладу в нее данные из семпла, делаю unlock и ставлю в очередь. данные я получаю в формате YUV, т.е. два байта на пиксель. поверхность создана соответствующая.
ov>в основном потоке я беру эту поверхность из очереди, на pixel shader'ах перевожу в rgb, разбиваю на поля и рисую эти поля с нужными коэффициентами прозрачности на экран в нужном месте. поверхность возвращаю в кеш.
Вы не смотрели профайлером когда съедается время? случайно не при копировании семплов на поверхность? если так, то может быть причина в том, что вы заставляете процессор копировать из оперативной памяти в видеопамять, а такое копирование как правило _очень_ медленное. Для решения трабла вам каким-то образом надо сделать так, чтобы видеокарта сама засасывала из оперативной памяти данные. Возможно это можно сделать через D3D функции, представив семпл как текстуру, которую нужно подгрузить в видепамять — вполне возможно что видеокарта будет это делать через свои DMA механизмы.
ov>>решал ли кто-нибудь такие задачи? может есть более шустрый способ? F>Делай свой рендерер, ставь ему PREFERRED FORMAT как RGB, и, возможно F>получиться в свой аллокатор подсунуть поинтер от поверхности D3D.
если поставить свой формат RGB, а не YUV, то в граф добавится Color Converter, что скорости не прибавит
на выходе будет минимум в 1.5 раза больше инфы, а если в RGBA, то в 2 раза больше.
F>Тогда всё будет быстрее некуда.
да не факт. с RGB точно медленнее будет. в YUV 2 байта на пиксел, меньше некуда, конвертация на шейдерах — быстрее способа нет.
F>Это в теории, на практике не пробовал, но вроде бы реализуемо.
а на практике-то все, как раз, фигово...
E>Вы не смотрели профайлером когда съедается время? случайно не при копировании семплов на поверхность? если так, то может быть причина в том, что вы заставляете процессор копировать из оперативной памяти в видеопамять, а такое копирование как правило _очень_ медленное. Для решения трабла вам каким-то образом надо сделать так, чтобы видеокарта сама засасывала из оперативной памяти данные. Возможно это можно сделать через D3D функции, представив семпл как текстуру, которую нужно подгрузить в видепамять — вполне возможно что видеокарта будет это делать через свои DMA механизмы.
проблема в том, что Lock поверхности возвращает адрес.
и в IMediaSample тоже приходит адрес. и по-любому надо копировать.
если залочить поверхность заранее и постараться подать ее декодеру, то возможны варианты, что он ее не возьмет и будет юзать свой аллокатор, а возможны варианты, что начнет глючить D3D и придется ставить безопасный многопоточный режим в нем, что съест скорость.
я вот сейчас как раз пытаюсь найти какой-то способ заставить видеокарту засасывать ресурсы самостоятельно, но что-то слабо верится в то, что это реально...
ov>если поставить свой формат RGB, а не YUV, то в граф добавится Color Converter, что скорости не прибавит
Ясен перец, что Color Converter убьёт всю идею на корню.
Попробуй разные RGB-space, а лучше посмотри на выходе декодера, какие типы он поддерживает.
Если RGB совсем не поддерживает, тогда труба. Может другой декодер поискать?
ov>на выходе будет минимум в 1.5 раза больше инфы, а если в RGBA, то в 2 раза больше.
Как это скажется на скорости, покажет эксперимент.
Видео-карты — они такие хитрые внутри...
ov>если поставить свой формат RGB, а не YUV, то в граф добавится Color Converter
Виталий, чтобы не добавлялся CSC нужно написать свой рендерер, который при проверке медиаформатов будет не по-байтно их сравнивать, а только значимые поля. Свой аллокатор на входном пине поможет избавиться от копирования данных из семплов в поверхность.
ov>на выходе будет минимум в 1.5 раза больше инфы, а если в RGBA, то в 2 раза больше.
Использование YUV — это не решение проблемы, так как рано или поздно понадобится и альфа.
Front
Re: DirectShow->D3D как можно быстрее
От:
Аноним
Дата:
15.11.06 08:15
Оценка:
ov>делаю так: при получении семпла в потоке фильтра беру из собственного кеша готовую d3d surface
Как решаете проблему синхронного получение семплов для видеотекстуры и асинхронности рендеринга основной сцены?
Здравствуйте, 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."
F>Ясен перец, что Color Converter убьёт всю идею на корню. F>Попробуй разные RGB-space, а лучше посмотри на выходе декодера, какие типы он поддерживает. F>Если RGB совсем не поддерживает, тогда труба. Может другой декодер поискать?
Извините, что влезаю, но какая в сущности разница где будет конвертация, внутри декодера или снаружи, если видео в потоке в YUV?