Перейти к содержанию
    

JPEG: определить величину качества для сжатия, при заданном размере буфера.

Есть кадр определённого размера M x N, который сжимается алгоритмом JPEG (YUV 4:2:0).  Есть выходной буфер, максимальный размер которого лимитирован (для передачи по эфиру) = V байт.

Зная M, N, V,  как определить параметр сжатия JPEG (% качества или QP), чтобы выходной сжатый фрейм уместился в буфере?

Условие вместиться в буфер - более приоритетное, чем наилучшее качество картинки.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

10 minutes ago, repstosw said:

Есть кадр определённого размера M x N, который сжимается алгоритмом JPEG (YUV 4:2:0).  Есть выходной буфер, максимальный размер которого лимитирован (для передачи по эфиру) = V байт.

Зная M, N, V,  как определить параметр сжатия JPEG (% качества или QP), чтобы выходной сжатый фрейм уместился в буфере?

Условие вместиться в буфер - более приоритетное, чем наилучшее качество картинки.

Дело в том, что степень сжатия JPEG зависит еще и от "сюжета" картинки..

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

16 minutes ago, repstosw said:

Зная M, N, V,  как определить параметр сжатия JPEG (% качества или QP), чтобы выходной сжатый фрейм уместился в буфере?

В вашей задаче (с избыточной мощностью кодера) можно несколько раз успеть кадр ужать, а потом уже выбрать подходящий по размеру.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

42 minutes ago, Джеймс said:

Дело в том, что степень сжатия JPEG зависит еще и от "сюжета" картинки..

Думал об этом.  В качестве самого "тяжёлого случая" взять высоко-энтропийный несжимаемый шум.

36 minutes ago, aaarrr said:

В вашей задаче (с избыточной мощностью кодера) можно несколько раз успеть кадр ужать, а потом уже выбрать подходящий по размеру.

Таже рассматриваю такой вариант.  Начинать сжатие с 90% и проверять размер, если превышает, уменьшить качество на и снова сжать.  Тут главное - успеть: выбрать шаг уменьшения качества.

C AVC H264 такой номер не прокатит: параметр QP должен быть постоянным на протяжении всего потока. А режим CBR AVC кодек не поддерживает (вроде?), да и никто не даст гарантии даже при CBR, что все сжатые фреймы не превысят определённое значение.

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 9/5/2022 at 9:24 AM, repstosw said:

Есть кадр определённого размера M x N, который сжимается алгоритмом JPEG (YUV 4:2:0).  Есть выходной буфер, максимальный размер которого лимитирован (для передачи по эфиру) = V байт.

Зная M, N, V,  как определить параметр сжатия JPEG (% качества или QP), чтобы выходной сжатый фрейм уместился в буфере?

Условие вместиться в буфер - более приоритетное, чем наилучшее качество картинки.

 

Я делал MJPEG - т.е. кадры шли друг за другом несколько раз в секунду.

При этом получается что степень сжатия от кадра к кадру не сильно меняется не зависимо от событий в кадре и освещённости.

Т.е. я определял степень сжатия текущего кадра по тому как сжался предыдущий.

Для степеней сжатия ZZ=5-999 и размера буфера 23540 байт формула была следующей:

Spoiler
if (R<17280) ZZ=ZZ+8;
else 
	{
	if (R<21600) ZZ=ZZ+1;
	else 
		{
		if (R<22400) ZZ=ZZ-1;
		else 
			{
			if (R<23500) ZZ=ZZ-8;
			else ZZ=ZZ-40;
			}
		}
	}
if (ZZ<5) ZZ=5;
if (ZZ>999) ZZ=999;

 

 

Тогда размеры менялись приблизительно так в потоке:

Spoiler

~0008C00: 0001 [00116:  S21452 Z521 ]
~000FA00: 0002 [00117:  S21514 Z522 ]
~0016800: 0003 [00118:  S21475 Z523 ]
~001D600: 0004 [00119:  S21513 Z524 ]
~0024400: 0005 [00120:  S21582 Z525 ]
~002B200: 0006 [00121:  S21551 Z526 ]
~0032000: 0007 [00122:  S21562 Z527 ]
~0038E00: 0008 [00123:  S21684 Z528 ]
~003FC00: 0009 [00124:  S22108 Z527 ]
~0046A00: 0010 [00125:  S22116 Z526 ]
~004D800: 0011 [00126:  S21632 Z525 ]
~0054600: 0012 [00127:  S21720 Z526 ]
~005B400: 0013 [00128:  S21768 Z525 ]
~0062200: 0014 [00129:  S21802 Z524 ]
~0069000: 0015 [00130:  S21790 Z523 ]
~006FE00: 0016 [00131:  S21887 Z522 ]
~0076C00: 0017 [00132:  S21842 Z521 ]
~007DA00: 0018 [00133:  S22276 Z520 ]
~0084800: 0019 [00134:  S21902 Z519 ]
~008B600: 0020 [00135:  S21896 Z518 ]
~0092400: 0021 [00136:  S21816 Z517 ]
~0099200: 0022 [00137:  S21853 Z516 ]
~00A0000: 0023 [00138:  S21838 Z515 ]
~00A6E00: 0024 [00139:  S22278 Z514 ]
~00ADC00: 0025 [00140:  S21826 Z513 ]
~00B4A00: 0026 [00141:  S21072 Z512 ]
~00BB800: 0027 [00142:  S22236 Z513 ]
~00C2600: 0028 [00143:  S21006 Z512 ]
~00C9400: 0029 [00144:  S21840 Z513 ]
~00D0200: 0030 [00145:  S21163 Z512 ]
~00D7000: 0031 [00146:  S22365 Z513 ]
~00DDE00: 0032 [00147:  S21097 Z512 ]
~00E4C00: 0033 [00148:  S21883 Z513 ]
~00EBA00: 0034 [00149:  S21025 Z512 ]
~00F2800: 0035 [00150:  S21723 Z513 ]
~00F9600: 0036 [00151:  S21112 Z512 ]
~0100400: 0037 [00152:  S21828 Z513 ]
~0107200: 0038 [00153:  S21047 Z512 ]
~010E000: 0039 [00154:  S21890 Z513 ]
~0114E00: 0040 [00155:  S21122 Z512 ]
~011BC00: 0041 [00156:  S21900 Z513 ]
~0122A00: 0042 [00157:  S21067 Z512 ]
~0129800: 0043 [00158:  S21762 Z513 ]
~0130600: 0044 [00159:  S21051 Z512 ]
~0137400: 0045 [00160:  S22302 Z513 ]
~013E200: 0046 [00161:  S20957 Z512 ]
~0145000: 0047 [00162:  S21670 Z513 ]
~014BE00: 0048 [00163:  S21491 Z512 ]
~0152C00: 0049 [00164:  S21663 Z513 ]
~0159A00: 0050 [00165:  S21705 Z514 ]

 

On 9/5/2022 at 9:24 AM, repstosw said:

(для передачи по эфиру)

Для передачи по эфиру я выкидывал первые 334 байта JPG на передающей стороне и передавал только степень сжатия ZZ, ну и ресинхронизацию в JPG включал.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

41 minutes ago, _4afc_ said:

Для степеней сжатия ZZ=5-999 и размера буфера 23540 байт формула была следующей:

Что такое степень сжатия ZZ?

Я работаю с libjpeg8, которая позволяет сформировать "подпорки" для JPEG - расчитать таблицы квантования и многое другое.

Там задаётся качество JPEG в процентах: 0..100% функцией:

jpeg_set_quality(&jcs, quality, TRUE);

 

Кодер JPEG аппаратный, работает очень быстро (время кодирования меньше 1 мс).

 

41 minutes ago, _4afc_ said:

Для передачи по эфиру я выкидывал первые 334 байта JPG на передающей стороне и передавал только степень сжатия ZZ, ну и ресинхронизацию в JPG включал.

Спасибо, что поделились данными своих результатов.  Попробую раскурить.

В качестве передатчика какой использовали - готовый чип или проектировали свой трансивер?  Связь наземная/подвижная с широконаправленными антеннами?   Или ПРД/ПРМ неподвижны  +направленные антенны?   Интересуюсь, потому что озадачен решить проблему межсивольной интерференции, которая возникает из-за многократных переотражений сигнала от объектов местности.

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 9/5/2022 at 2:36 PM, repstosw said:

Что такое степень сжатия ZZ?

Я работаю с libjpeg8, которая позволяет сформировать "подпорки" для JPEG - расчитать таблицы квантования и многое другое.

Там задаётся качество JPEG в процентах: 0..100% функцией:

 

quality=ZZ/10;

в ходе рефакторинга некого кодера увеличил точность степени сжатия в 10 раз для удобства.

 

Вы попробуйте - для каждого  quality будут свои фиксированные "таблицы квантования и многое другое" нет смысла гнать их по эфиру, ведь искажение любого бита в них приведёт к потере кадра.

Всегда можно восстановить заголовок на приёме загнав в ваш libjpeg8 любые данные с требуемым quality - на кодирование.

 

On 9/5/2022 at 2:36 PM, repstosw said:

В качестве передатчика какой использовали - готовый чип или проектировали свой трансивер?  Связь наземная/подвижная с широконаправленными антеннами?   Или ПРД/ПРМ неподвижны  +направленные антенны?   Интересуюсь, потому что озадачен решить проблему межсивольной интерференции, которая возникает из-за многократных переотражений сигнала от объектов местности.

Свой. Стационарный ЧМ. При увеличении переотражений - связь была не возможна.

 

Но это было давно... дерзайте.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, _4afc_ said:

Вы попробуйте - для каждого  quality будут свои фиксированные "таблицы квантования и многое другое" нет смысла гнать их по эфиру, ведь искажение любого бита в них приведёт к потере кадра.

Всегда можно восстановить заголовок на приёме загнав в ваш libjpeg8 любые данные с требуемым quality - на кодирование.

В конечном итоге, так и хочу сделать.

1 hour ago, _4afc_ said:

Но это было давно... дерзайте.

Жду когда дойдут модули трансиверов.

Пока не определился с кодером - либо H264 либо JPEG.  

Если H264(AVC), то делать каждый фрейм ключевым, чтобы избежать неизбежных ошибок в последующих фреймах. У AVC тоже есть параметр качества, с постоянным битрейтом он не работает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проделал эксперимент.

Фрейм 160x128, 12.5 кадров в секунду. Изображения берутся с камеры и сжимаются аппаратным JPEG-кодером. Размер буфера задан 2048 байт.

Прилепливается заголовок таблицы квантования - до полноценного JPEG. Всё это дело пишется в файл.  По истечению определённого времени получившийся файл(MJPEG) смотрится на ПК (с помощью MPC HC плеера).

Начальное значение качества: QUALITY=10 (10%)

По мере кодирования, с каждым новым кадром качество повышается на 10%. Если не укладываемся в размер буфера - снижаем качество на 10%.

При таком раскладе: при старте качество вначале быстро повышается, затем оно(значение качества) осциллирует.  Тем самым достигается минимальное число перекодирований.

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

Алгоритм:

int QUALITY=10;

void jpeg_encode(void)
{
	ReEncode:

	SetQuality(QUALITY);

	JPEG_Encode();

	if(JPEGSize>2048)
	{
	 QUALITY-=10;
	 if(QUALITY<10)QUALITY=10;
                           
	 goto ReEncode;
	}

	UART2_putn(QUALITY);

	QUALITY+=10;
	if(QUALITY>90)QUALITY=90;
}

Лог значений качества для каждого фрейма(видео, 10 секунд, 12,5 FPS):

Quote

Start...
10
20
30
40
50
60
60
60
60
50
50
50
50
50
50
50
50
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
50
40
40
40
50
40
50
50
40
40
40
40
30
40
40
40
40
40
40
40
40
40
40
50
50
60
60
70
70
70
70
70
70
70
70
70
70
70
70
70
70
70
70
70
70
60
60
60
60
60
60
60
60
60
60
60
60
50
50
40
30
30
30
30
30
30
30
30
30
30
40
40
50
50
50
60
60
60
60
50
60
60
60
60
60
60
60
60
60
60
60
OK!

image.thumb.png.2f64946cae35663eb662ff38fe087be4.png

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, repstosw said:

Видео довольно динамичное - говорящий собеседник, показывающий разные предметы в камеру

По жизни самые сложные сцены - деревья и кусты. Проще говоря - чем больше контрастных участков на изображении, тем сложнее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

15 hours ago, repstosw said:

Если H264(AVC), то делать каждый фрейм ключевым, чтобы избежать неизбежных ошибок в последующих фреймах. У AVC тоже есть параметр качества, с постоянным битрейтом он не работает.

Обычно меняется величина квантователя для каждого макробока. Т.е. сперва устанавливается первоначальное усредненное значение, исходя из получаемого битстрима, и далее железо само вычисляет применительно к текущему макроблоку.

Изменено пользователем lexx

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 hours ago, Ozelot said:

По жизни самые сложные сцены - деревья и кусты. Проще говоря - чем больше контрастных участков на изображении, тем сложнее.

:) Я называл это участками с резким перепадом цветов, например:  мелкая сетка или угол стола на фоне обоев :) Качество JPEG в этих местах хромает, если % низкий.

23 hours ago, repstosw said:

C AVC H264 такой номер не прокатит: параметр QP должен быть постоянным на протяжении всего потока.

Уже прокатил.  Удалось установить кодеру AVC H264 режим, когда каждый кадр ключевой. Для того, чтобы поток, состоящий из фреймов с разным QP открылся на ПК, нужно каждый раз перед сжатым фреймом передавать 3 хедера:

SPS, PPS и SLICE.

Причём первые два хедера одинаковые всегда, а у последнего меняются последние 4 байта.  По понятным причинам, в эфир можно передавать только сжатый фрейм + последние 4 байта хедера SLICE. и величину QP (SLICE тоже можно не передавать - последние 4 байта - зависят от QP). Остальное приклеивать.

image.thumb.png.6c48478196baf4a1bd875508814fb95d.pngimage.thumb.png.f87a9bed37e9e4bbb8f1358f4a10b9c3.png

В качестве проверки, из получившегося потока пробовал вырезать одиночные фреймы - они валидные и воспроизводятся на ПК.

Чисто субъективно, при том же ограничении выходного буфера, качество кодера H264(AVC) лучше, чем у JPEG - у H264 искажения на мелких деталях не так сильно бросаются в глаза.

QP варьируется от 1(самый лучший) до 47(самый ужасный).

Лог QP в видео H264 (160x128 12,5 FPS):

Quote

35
34
33
32
31
30
29
28
27
26
25
24
23
23
23
23
23
23
23
22
23
23
23
22
23
23
23
22
23
23
23
22
23
23
23
22
23
23
23
22
23
23
24
23
24
24
25
24
24
23
24
23
24
24
23
23
23
24
23
24
26
27
27
27
27
26
27
27
27
27
27
27
27
27
27
26
26
25
24
24
25
26
26
25
25
25
25
26
25
25
24
24
24
25
24
23
23
23
23
24
25
24
24
24
24
23
24
25
26
26
26
27
30
30
29
29
30
29
29
28
29
29
29
28
29

image.thumb.png.1448ca79ff2226fe58bedfc902776f2a.png

1 hour ago, lexx said:

Обычно меняется величина квантователя для каждого макробока. Т.е. сперва устанавливается первоначальное усредненное значение, исходя из получаемого битстрима, и далее железо само вычисляет применительно к текущему макроблоку.

Таких возможностей кодек AVC(H264) в Allwinner не предоставляет.  Всё что есть - это 2 параметра QP на компоненты яркости и цвета.

Есть ещё другой кодек H264 - не AVC который, вот он умеет CBR.  Только опять же, нет гарантии, что очередной фрейм уложится в ограничение буфера.

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 9/6/2022 at 3:18 PM, repstosw said:

Удалось установить кодеру AVC H264 режим, когда каждый кадр ключевой.

Вы скорее всего сделали его IDR, т.е. первый ключевой, возможно поэтому заголовки повторяются (хотя там ногу сломит в реализации), нужно про Intra only.

Можно поиграться с параметрами, но раз результат устраивает, то лучше остановиться на этом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...