Покопался немного в своей программке сжатия. Выяснил, что никакой ошибки в работе с динамической памятью у меня не было.
Похоже, это любо глюк Delphi, либо Windows. Или, наоборот, это фича такая?
При многократном рендеринге в битмап возникает "тихая" ошибка. Точнее, с какой-то итерации рендеринг прекращается, ошибки не возникает, а исходный битмап не меняется. Рендеринг, это на самом деле BitBlt с десктопа. Идея была в том, что бы не создавать на каждой итерации TBitmap, а просто рендерить в один раз созданный. Естественно, ради производительности. Но, похоже, издержки по создания TBitmap не так уж высоки, поэтому пока отложил этот вопрос куда-то в неопределенное будущее.
Параллельно посмотрел статистику, какие же операции наиболее затратные при сжатии видео. У меня были некие идеи о том, какие операции будут наиболее медленным. Но я их вообще не угадал. )))
| Процесс | Время, с | % от общего времени |
| Screen copy | 14.724 | 11.60% |
| Color conversation | 13.649 | 10.75% |
| Wavelet conversation | 57.431 | 45.24% |
| Data loss reduction | 23.41 | 18.44% |
| RLE reduction | 13.087 | 10.31% |
| Haffman coding | 4.65 | 3.66% |
Совершенно неожиданно, больше всего заняло wavelet-преобразование, несмотря на его простоту. Соответственно, можно ожидать и большого эффекта от оптимизации этого кода.
Планирую использовать два подхода при оптимизации. Первый - это SIMD, так как wavelet-преобразование производится на каждой точке изображения. Теоретически, в зависимости от используемого набора команд SSE, следует ожидать 4-х или 8-ми кратного прироста производительности. На практике, для таких команд надо еще подготовить данные, а потом их разобрать. Поэтому прирост окажется скромнее, но все равно должен быть значительным.
Второй подход состоит в том, что 2, 3 и 4 пункты можно объединить и выполнять в одной процедуре. Каждая из этих процедур обрабатывает целиком все внутреннее представление изображения, которое занимает достаточно солидный объем. Выигрыш здесь потенциально состоит в том, что данные чаще будут попадать в кэш, это снизит нагрузку на подсистему памяти и повысит производительность. Но будет ли существенный эффект от этого?
С другой стороны, наличие большого количества этапов сжатия позволит организовать длинный конвейер в случае многопоточного варианта сжатия. Это также может поднять производительность, но несколько противоречит второму подходу. Поэтому пока раздумываю, нужно ли это.
Также можно примерно оценить и то, сколько можно снять копий экрана в секунду, при максимальной загрузке одного ядра и использовании операции BitBlt. По результатам статистики, если убрать все остальные операции, это даст примерно 9 кадров в секунду. С учетом того, что ядро в текущем варианте загружено в среднем на 30-40 процентов, можно ожидать съема до 20-30 кадров в секунду.