Цитата(Stanislav @ Apr 13 2008, 22:21)

Читаем описание алгоритма TTA
так вот 1сек размер фрейма связан с тем, что формат файлово-ориентированный (что впрочем не мешает его модифицировать в потоковый) и основное требование - возможность позиционирования в произвольное место файла. если мы заглянем в исходники то мы увидим след (я буду комментировать происходящее по версии 3.0 - разница с последними версиями незначительна а код читается лучше):
Код
int compress(FILE *fdin, FILE *fdout) {
while (fframes--) {
read_wave(data, byte_size, framelen * (num_chan >> is_float), fdin);
encoder_init(tta, num_chan, byte_size);
for (p = data, prev = 0; p < data + framelen * num_chan; p++) {
// compress stage 1: fixed order 1 prediction
case 2: *p -= PREDICTOR1(*last, 5); break; // bps 16
// compress stage 2: adaptive hybrid filter
hybrid_filter(fst, p, 1);
value = ENC(*p);
// encode Rice unsigned
put_unary(unary);
}
}
// update the seek table
это очень поскипанный код. но суть будет понятна. для каждого фрейма читаем его, инициализируем таблицы накапливающие статистики Rice кодера, для каждого семпла вызываем тривиальный PREDICTOR1:
Код
#define PREDICTOR1(x, k) ((long)((((uint64)x << k) - x) >> k))
после чего прогоняем через т.н. гибридный фильтр, после чего кодируем райсом и обновляем статистики этого самого райса.
легко заметить следующее:
1. семпл попадает на выход без всяких задержек! т.е. для его кодирования нам необходима только информация о предыдущих семплах, но не о будущих.
2. требование позиционирования = возможность декодировать любой произвольный блок из потока в случайном порядке (radnom access) приводит к тому что мы вынуждены сбрасывать статистики Rice и гибридного фильтра в начале каждого блока. если с фильтром не все так критично, то сброс статистик Rice естественно приводит к ухудшению сжатия. именно поэтому разработчики определили размер фрейма в 1 сек как компромис между ухудшением сжатия и точностью позиционирования при random access
3. никакой допинформации кроме как маркера для позиционирования в файле с фреймом не связывается. для статистик Rice используется backward adaptation - т.е. декодер накапливает эти статистики в процессе декодирования и параметры кода в явном виде передавать не надо.
TTA элементарно преобразовывается в потоковый алгоритм. никаких задержек в 1 сек естественно не будет. понятие фрема зависит от того как мы будем принимать поток. если мы принимаем поток от начала и до конца и канал гарантирует доставку пакетов клиенту без пропусков - тогда можно все передать одним фреймом не сбрасывая статистики. это благоприятно скажется на сжатии. если у нас броадкастинг - т.е. клиент может подключиться в произвольный момент времени - тоже ничего страшного. делаем маркеры с интервалом одна сек, по ним обнуляем статистику. клиент ждет маркера и после его получения (макс 1 сек ожидания) начинает синхронно декодировать поток.
почему это все так важно? дело в том что TTA использует те самые техники в которых наш знайка ни в зуб ногой. а именно Rice и backward adaptation. т.е. декодер синхронно с процессом декодирования набирает статистику которая позволяет ему правильно декодировать коды Rice