repstosw 18 5 сентября, 2022 Опубликовано 5 сентября, 2022 · Жалоба Есть кадр определённого размера M x N, который сжимается алгоритмом JPEG (YUV 4:2:0). Есть выходной буфер, максимальный размер которого лимитирован (для передачи по эфиру) = V байт. Зная M, N, V, как определить параметр сжатия JPEG (% качества или QP), чтобы выходной сжатый фрейм уместился в буфере? Условие вместиться в буфер - более приоритетное, чем наилучшее качество картинки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Джеймс 4 5 сентября, 2022 Опубликовано 5 сентября, 2022 · Жалоба 10 minutes ago, repstosw said: Есть кадр определённого размера M x N, который сжимается алгоритмом JPEG (YUV 4:2:0). Есть выходной буфер, максимальный размер которого лимитирован (для передачи по эфиру) = V байт. Зная M, N, V, как определить параметр сжатия JPEG (% качества или QP), чтобы выходной сжатый фрейм уместился в буфере? Условие вместиться в буфер - более приоритетное, чем наилучшее качество картинки. Дело в том, что степень сжатия JPEG зависит еще и от "сюжета" картинки.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 5 сентября, 2022 Опубликовано 5 сентября, 2022 · Жалоба 16 minutes ago, repstosw said: Зная M, N, V, как определить параметр сжатия JPEG (% качества или QP), чтобы выходной сжатый фрейм уместился в буфере? В вашей задаче (с избыточной мощностью кодера) можно несколько раз успеть кадр ужать, а потом уже выбрать подходящий по размеру. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 5 сентября, 2022 Опубликовано 5 сентября, 2022 (изменено) · Жалоба 42 minutes ago, Джеймс said: Дело в том, что степень сжатия JPEG зависит еще и от "сюжета" картинки.. Думал об этом. В качестве самого "тяжёлого случая" взять высоко-энтропийный несжимаемый шум. 36 minutes ago, aaarrr said: В вашей задаче (с избыточной мощностью кодера) можно несколько раз успеть кадр ужать, а потом уже выбрать подходящий по размеру. Таже рассматриваю такой вариант. Начинать сжатие с 90% и проверять размер, если превышает, уменьшить качество на и снова сжать. Тут главное - успеть: выбрать шаг уменьшения качества. C AVC H264 такой номер не прокатит: параметр QP должен быть постоянным на протяжении всего потока. А режим CBR AVC кодек не поддерживает (вроде?), да и никто не даст гарантии даже при CBR, что все сжатые фреймы не превысят определённое значение. Изменено 5 сентября, 2022 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_4afc_ 26 5 сентября, 2022 Опубликовано 5 сентября, 2022 · Жалоба 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 включал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 5 сентября, 2022 Опубликовано 5 сентября, 2022 (изменено) · Жалоба 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 включал. Спасибо, что поделились данными своих результатов. Попробую раскурить. В качестве передатчика какой использовали - готовый чип или проектировали свой трансивер? Связь наземная/подвижная с широконаправленными антеннами? Или ПРД/ПРМ неподвижны +направленные антенны? Интересуюсь, потому что озадачен решить проблему межсивольной интерференции, которая возникает из-за многократных переотражений сигнала от объектов местности. Изменено 5 сентября, 2022 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_4afc_ 26 5 сентября, 2022 Опубликовано 5 сентября, 2022 · Жалоба 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: В качестве передатчика какой использовали - готовый чип или проектировали свой трансивер? Связь наземная/подвижная с широконаправленными антеннами? Или ПРД/ПРМ неподвижны +направленные антенны? Интересуюсь, потому что озадачен решить проблему межсивольной интерференции, которая возникает из-за многократных переотражений сигнала от объектов местности. Свой. Стационарный ЧМ. При увеличении переотражений - связь была не возможна. Но это было давно... дерзайте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 5 сентября, 2022 Опубликовано 5 сентября, 2022 · Жалоба 1 hour ago, _4afc_ said: Вы попробуйте - для каждого quality будут свои фиксированные "таблицы квантования и многое другое" нет смысла гнать их по эфиру, ведь искажение любого бита в них приведёт к потере кадра. Всегда можно восстановить заголовок на приёме загнав в ваш libjpeg8 любые данные с требуемым quality - на кодирование. В конечном итоге, так и хочу сделать. 1 hour ago, _4afc_ said: Но это было давно... дерзайте. Жду когда дойдут модули трансиверов. Пока не определился с кодером - либо H264 либо JPEG. Если H264(AVC), то делать каждый фрейм ключевым, чтобы избежать неизбежных ошибок в последующих фреймах. У AVC тоже есть параметр качества, с постоянным битрейтом он не работает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 6 сентября, 2022 Опубликовано 6 сентября, 2022 (изменено) · Жалоба Проделал эксперимент. Фрейм 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! Изменено 6 сентября, 2022 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ozelot 9 6 сентября, 2022 Опубликовано 6 сентября, 2022 · Жалоба 1 hour ago, repstosw said: Видео довольно динамичное - говорящий собеседник, показывающий разные предметы в камеру По жизни самые сложные сцены - деревья и кусты. Проще говоря - чем больше контрастных участков на изображении, тем сложнее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lexx 0 6 сентября, 2022 Опубликовано 6 сентября, 2022 (изменено) · Жалоба 15 hours ago, repstosw said: Если H264(AVC), то делать каждый фрейм ключевым, чтобы избежать неизбежных ошибок в последующих фреймах. У AVC тоже есть параметр качества, с постоянным битрейтом он не работает. Обычно меняется величина квантователя для каждого макробока. Т.е. сперва устанавливается первоначальное усредненное значение, исходя из получаемого битстрима, и далее железо само вычисляет применительно к текущему макроблоку. Изменено 6 сентября, 2022 пользователем lexx Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 6 сентября, 2022 Опубликовано 6 сентября, 2022 (изменено) · Жалоба 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). Остальное приклеивать. В качестве проверки, из получившегося потока пробовал вырезать одиночные фреймы - они валидные и воспроизводятся на ПК. Чисто субъективно, при том же ограничении выходного буфера, качество кодера 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 1 hour ago, lexx said: Обычно меняется величина квантователя для каждого макробока. Т.е. сперва устанавливается первоначальное усредненное значение, исходя из получаемого битстрима, и далее железо само вычисляет применительно к текущему макроблоку. Таких возможностей кодек AVC(H264) в Allwinner не предоставляет. Всё что есть - это 2 параметра QP на компоненты яркости и цвета. Есть ещё другой кодек H264 - не AVC который, вот он умеет CBR. Только опять же, нет гарантии, что очередной фрейм уложится в ограничение буфера. Изменено 6 сентября, 2022 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lexx 0 20 сентября, 2022 Опубликовано 20 сентября, 2022 · Жалоба On 9/6/2022 at 3:18 PM, repstosw said: Удалось установить кодеру AVC H264 режим, когда каждый кадр ключевой. Вы скорее всего сделали его IDR, т.е. первый ключевой, возможно поэтому заголовки повторяются (хотя там ногу сломит в реализации), нужно про Intra only. Можно поиграться с параметрами, но раз результат устраивает, то лучше остановиться на этом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться