Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Cortex-M4F и сжатие видео на ходу
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Forger
Подскажите, плиз, кто имел опыт сжатия видео на ходу на Cortex-M4F, в частности на STM32F4 или другом проце на таком ядре.
Возможно ли сжать на этих МК на ходу видео 320x240, 2 байта на пиксель, 25 fps и выше?
Скажем, в формат MJPEG. Исходные данные идут в формате YCbCr 4:2:2 или RGB565.
Если это анреал, то что посоветуете дешевое, без линуксов и с нормальным (IDE).
_pv
для оценки можно взять циферки от блэкфина
http://www.analog.com/en/dsp-software/bf_j...on-jpeg/sw.html
и на 2, а то и на 3 помножить.
jpeg - 50 блэкфиновских тактов на пиксель.
320*240*25 = 2МПикс/сек. то есть по хорошему кортексу надо бы 200-300МГц.
с видео енкодерами с межкадровым сжатием (mpeg) всё еще хуже.
можно конечно попробовать что-нибудь своё сгородить, тупо дельта кодирование или даже какой-нибудь простейший вэйвлет хаара (полусумма/полуразность, да еще и трехмерный, чтоб по времени) + энтропийное кодирование, но, имхо, если оно и влезет по быстродействию, сжатие будет не большое.
да и с внешней памятью у STM32F4 через FSMC общение не самое быстрое, сколько там максимум, на 56МГц цикл шины?
хотя у F429 есть и sdram контроллер и некие ухищрения в дма для графики, но не сильно это поможет.
Forger
Цитата(_pv @ Nov 27 2013, 00:38) *
да и с внешней памятью у STM32F4 через FSMC общение не самое быстрое, сколько там максимум, на 56МГц цикл шины?

На 25fps поток выходит почти 4Мбайт/сек, а для 16-битной внешней SRAM выйдет почти 2Мслова в сек.
При использовании DMA перегон данных туда-сюда не сильно грузит проц.
Я как-то сравнивал: DMA2 гнал данные из DCMI (камера OV7725) в ЖК по FSMC.
Так вот нагрузка на проц на 168Мгц вырастала всего лишь на 0.2% (под TNKernel).

Межкадровое кодирование необязательно, хватит обычного MJPEG.

Т.е. вы считаете, что не потянет?
На каком проце лучше это поднять?
Нужен аппаратный интерфейс для работы с камерой и ЖК, USB device и нормальная среда и библиотеки для сжатия видео по возможности.
jcxz
Цитата(Forger @ Nov 27 2013, 11:21) *
На 25fps поток выходит почти 4Мбайт/сек, а для 16-битной внешней SRAM выйдет почти 2Мслова в сек.
При использовании DMA перегон данных туда-сюда не сильно грузит проц.
Я как-то сравнивал: DMA2 гнал данные из DCMI (камера OV7725) в ЖК по FSMC.
Так вот нагрузка на проц на 168Мгц вырастала всего лишь на 0.2% (под TNKernel).

По-моему некорректное измерение.
А Вы учли, что DMA занимает шину и если при отсутствии этого потока какие-то процессорные вычисления занимали N тактов,
то при работающем DMA они уже будут занимать N+X тактов из-за ожиданий освобождения шины?
Forger
Цитата(jcxz @ Nov 27 2013, 09:53) *
По-моему некорректное измерение.
А Вы учли, что DMA занимает шину и если при отсутствии этого потока какие-то процессорные вычисления занимали N тактов,
то при работающем DMA они уже будут занимать N+X тактов из-за ожиданий освобождения шины?

Почему некорректно?
Перед запуском всем процессов (в каждом процессе может быть несколько потоков) я замеряю за фиксированное время число входжений в idle поток.
После пуска процессов сравниваю число вхождений в idle поток за тот же интервал времени с ранее замерянным без заботающих процессов.
Разумеется здесь не учитываются накладные насходы RTOS.
Так вот запуск процесса, который снимает картинку с камеры (~30fps) и кидает на экран (320x240) увеличивал загрузку с 1,5 до 1,7%.
Но давайте не будем отклоняться от темы... )))
jcxz
Цитата(Forger @ Nov 27 2013, 12:15) *
Почему некорректно?
...
Так вот запуск процесса, который снимает картинку с камеры (~30fps) и кидает на экран (320x240) увеличивал загрузку с 1,5 до 1,7%.
Но давайте не будем отклоняться от темы... )))

Потому, что у вас загрузка всего 1.5%, т.е. - CPU почти ничего не делает, крутится в малом регионе кода, который практически весь в кеше.
Допустим у вас есть уже задача1, которая активно работает с ОЗУ и при её старте загрузка CPU увеличивается на 30% и становится равным 31.5% (т.е. - сама задача1 ест 30% времени CPU).
Далее - запускаем ваш DMA-поток, загрузка CPU ==1.7%. Далее - запускаем задачу1. И сколько будет загрузка CPU? Думаете 31.7%? Я думаю - будет значительно больше, увеличение уже
будет не на 30%, а скажем - на 35%.
Это потому, что вы в своём расчёте загрузки CPU не учитываете загрузку шины.

Цитата(Forger @ Nov 27 2013, 12:15) *
Перед запуском всем процессов (в каждом процессе может быть несколько потоков) я замеряю за фиксированное время число входжений в idle поток.

Число вхождений? Это как? И почему так?
Вроде стандартный метод: замерить кол-во проходов некоего цикла за фиксированный интервал при нулевой загрузке CPU, получить N.
Потом за этот-же интервал замерять кол-во проходов этого-же цикла при работающей системе, получать M. И находить отношение в % M/N.
Ozelot
Может используйте сенсоры со встроеным JPEG-энкодером (например MT9D111 или OV5642).
Если нужно оцифровывать и сжимать аналоговый видеосигнал, то можно использовать связку видеодекодер и SSD1928, в этом случае тоже сжатие JPEG.
_pv
Цитата(Forger @ Nov 27 2013, 11:21) *
На 25fps поток выходит почти 4Мбайт/сек, а для 16-битной внешней SRAM выйдет почти 2Мслова в сек.
При использовании DMA перегон данных туда-сюда не сильно грузит проц.
Межкадровое кодирование необязательно, хватит обычного MJPEG.
Т.е. вы считаете, что не потянет?

вопрос в том сколько раз туда-сюда данные надо будет гонять для сжатия видео в какой-нибудь mpeg.
для jpegа да, только один раз прочитать надо в буфер на 8 строк,
ну а 50 тактов на пиксель для блэкфина говорят о том что не потянет, кадров 10 в секунду, наверное, получится.
Forger
Цитата(jcxz @ Nov 27 2013, 11:05) *
Потому, что у вас загрузка всего 1.5%, т.е. - CPU почти ничего не делает, крутится в малом регионе кода, который практически весь в кеше.

Делает. В RTOS есть системный таймер, который переключает потоки принудительно.

Цитата
Число вхождений? Это как? И почему так?

В бесконечном цикле потока idle стоит инкремент некой переменной. И больше ничего.
Мы говорим от об одном и том же. Вероятно, я неудачно объяснил...

Цитата
Вроде стандартный метод: замерить кол-во проходов некоего цикла за фиксированный интервал при нулевой загрузке CPU, получить N.
Потом за этот-же интервал замерять кол-во проходов этого-же цикла при работающей системе, получать M. И находить отношение в % M/N.

По сути, именно так я и делаю. Только не заставляю проц заниматься бесполезной работой по хождения по неким циклам.
Достаточно просто замерить сколько времени проц проводит в ilde потоке, относительно варианта, когда нет ни одного потока, кроме idle.



Цитата(Ozelot @ Nov 27 2013, 11:20) *
Может используйте сенсоры со встроеным JPEG-энкодером (например MT9D111 или OV5642).

Не подходят - нужна оч. высокая чувствительность, в OV7725 пиксель имеет размер аж 6 микрометров, чувствительность 3.8В/lux*c. Но у него нет JPEG.

MT9D111 - пиксель 2.8um, а чувствительность 1В/lux*c
OV5642 - пиксель 1.4um, а чувствительность всего 0.68В/lux*c
Поэтому не подходят ((

Цитата
Если нужно оцифровывать и сжимать аналоговый видеосигнал, то можно использовать связку видеодекодер и SSD1928, в этом случае тоже сжатие JPEG.

Сигнал цифровой, на исходном изображении с камеры требуется дорисовка некоторых картинок и текстов.
MAX7456 и им подобные для видео сигнала - пройденный этам, не годятся.
Поэтому работа исключительно с цифрой.
Ozelot
Цитата(Forger @ Nov 27 2013, 14:14) *
Сигнал цифровой, на исходном изображении с камеры требуется дорисовка некоторых картинок и текстов.
MAX7456 и им подобные для видео сигнала - пройденный этам, не годятся.
Поэтому работа исключительно с цифрой.


SSD1928 может и цифру сжимать в JPEG (гляньте даташит). К тому же у него очень низкое энергопотребление.
Вот только не знаю как сделать наложение sad.gif
_pv
Цитата(Forger @ Nov 27 2013, 11:21) *
На каком проце лучше это поднять?
Нужен аппаратный интерфейс для работы с камерой и ЖК, USB device и нормальная среда и библиотеки для сжатия видео по возможности.

посмотрите на adsp-bf512, всё кроме наличия USB подходит. среда нормальная, только дорогая, если покупать.

можно еще в adsp-bf592 попробовать впихнуть, jpeg на лету он пожалуй осилит, но вот внешней шины памяти нет совсем, то есть картинку надо сжать и куда-то сразу же отправить дальше, хранить не где. ну и соответственно дисплей опять же подключать придётся через непонятно что, хотя 320х240 и на SPI повесть можно.

ну а дальше идут cortexы-A*, с линуксом и в некрасивых корпусах, зато любое видеосжатие потянут, хотя allwinner 13 или iMX233 в есть и в qfp.
https://www.olimex.com/Products/OLinuXino/A13/
https://www.olimex.com/Products/OLinuXino/iMX233/
Forger
Цитата(Ozelot @ Nov 27 2013, 15:46) *
SSD1928 может и цифру сжимать в JPEG (гляньте даташит). К тому же у него очень низкое энергопотребление.
Вот только не знаю как сделать наложение sad.gif

Согласен, чип действительно интересный - напрямую работает с камерой и экраном, внутри есть 256кб озу для картинки, этого вполне достаточно для 320x240.
К нему тока нужен любой дешевый МК с нужной периферией. Спасибо за наводку ))


Цитата(_pv @ Nov 27 2013, 16:25) *
посмотрите на adsp-bf512..... но вот внешней шины памяти нет совсем

Наверно вы что-то путаете, контроллер памяти у них есть:
Memory controller providing glue-less connection to multiple banks of external SDRAM, SRAM, Flash, or ROM
Цитата
ну а дальше идут cortexы-A*, с линуксом и в некрасивых корпусах, зато любое видеосжатие потянут, хотя allwinner 13 или iMX233 в есть и в qfp.
https://www.olimex.com/Products/OLinuXino/A13/
https://www.olimex.com/Products/OLinuXino/iMX233/

Увы, наблюдается некий разрыв - либо максимум Cortex-M4F с удобным тулчейном (тот же привычный keil), либо BGA-монстры, которые даже слишком круты для моей задачи, не вся нужная периферия на борту, да и тулчейн под них - отдельный разговор...
_pv
Цитата(Forger @ Nov 27 2013, 19:37) *
Наверно вы что-то путаете, контроллер памяти у них есть:
Memory controller providing glue-less connection to multiple banks of external SDRAM, SRAM, Flash, or ROM

у BF512 есть, я говорил про BF592 который стоит 4-5$ и в qfn64 корпусе - у него нет.

Цитата(Forger @ Nov 27 2013, 19:37) *
Увы, наблюдается некий разрыв - либо максимум Cortex-M4F с удобным тулчейном (тот же привычный keil), либо BGA-монстры, которые даже слишком круты для моей задачи, не вся нужная периферия на борту, да и тулчейн под них - отдельный разговор...

я как раз привёл примеры процессоров в qfp корпусах. тулчейн - да, по сравнению с привычным кейлом придётся пошаманить, но нельзя сказать что его нет.
yes
у BF есть lqfp корпуса, есть индусский пример JPEG-а
ну и для JPEG-а не нужна память на весь кадр, достаточно 16 строк YCbCr 4:2:2 (вернее 32 строки с пинг-понг буфером, но может и можно хитрее)
делал на внутренней памяти 533 - вроде работало на 15fps, но это и руки кривые и работал в режиме "выходного дня"
ну и bga корпуса там до 700, а это 300МГц.

сейчас бы брал какой-нибудь готовый "апликейшен" проц типа i.mx там за 10$ наверно можно найти со встроенным кодером
Forger
Цитата(_pv @ Nov 27 2013, 12:37) *
вопрос в том сколько раз туда-сюда данные надо будет гонять для сжатия видео в какой-нибудь mpeg.
для jpegа да, только один раз прочитать надо в буфер на 8 строк,
ну а 50 тактов на пиксель для блэкфина говорят о том что не потянет, кадров 10 в секунду, наверное, получится.

Ради интереса я взял вот это довольно просто написанный JPEG-кодек: Jpegant.
Убрал оттуда преобразование RGB->YCrCb (к счастью, хотя бы это камера OV7725 умеет делать сама).
Осталось только DCT преобразование и huffman сжатие.
Проц STM32F407VG на 168МГц, кроме как кодирование картинки он ничего не делает (ну крутится еще RTOS, но я ее тут не считаю).
Изображение берется из внутренней ОЗУ, благо для хранения картинки 320x240x2байта его хватает.
Оптимизация файлов кодека -O3 -Otime (Keil 4.72.10).

Так вот. в пределе выходит 25fps.

Ради интереса попробовал включить RGB->YCrCb преобразование, то fps резко упало до 15.
Если покопаться в исходниках кодека и оптимизировать его под Cortex-M4F, то, я уверен, что fps можно еще поднять на несколько кадров.

В принципе, вот весь код сжатия картинки:
CODE
huffman_start(240, 320);
for (unsigned y = 0; y < (240-15); y += 16)
{
for (unsigned x = 0; x < (320-15); x += 16)
{
getBlock(x, y, 16, 16, (BGR*)RGB16x16)); // take picture block from IRAM
/*
// geting four 8x8 Y-blocks
for (unsigned i = 0; i < 2; i++)
for (unsigned j = 0; j < 2; j++)
{
for (unsigned r = 0; r < 8; r++)
for (unsigned c = 0; c < 8; c++)
{
const unsigned rr = (i<<3) + r;
const unsigned cc = (j<<3) + c;

Color red = RGB16x16[rr][cc].red;
Color green = RGB16x16[rr][cc].green;
Color blue = RGB16x16[rr][cc].blue;

// converting RGB into Y (luminance)
Y8x8[i][j][r][c] = RGB2Y(red, green, blue)-128;
}
}
// getting subsampled Cb and Cr
subsample(RGB16x16, Cb8x8, Cr8x8);
*/
// 1 Y-compression
dct(Y8x8[0][0], Y8x8[0][0]);
huffman_encode(HUFFMAN_CTX_Y, (short*)Y8x8[0][0]);

// 2 Y-compression
dct(Y8x8[0][1], Y8x8[0][1]);
huffman_encode(HUFFMAN_CTX_Y, (short*)Y8x8[0][1]);

// 3 Y-compression
dct(Y8x8[1][0], Y8x8[1][0]);
huffman_encode(HUFFMAN_CTX_Y, (short*)Y8x8[1][0]);

// 4 Y-compression
dct(Y8x8[1][1], Y8x8[1][1]);
huffman_encode(HUFFMAN_CTX_Y, (short*)Y8x8[1][1]);

// Cb-compression
dct(Cb8x8, Cb8x8);
huffman_encode(HUFFMAN_CTX_Cb, (short*)Cb8x8);

// Cr-compression
dct(Cr8x8, Cr8x8);
huffman_encode(HUFFMAN_CTX_Cr, (short*)Cr8x8);

}
}
huffman_stop();
_pv
Цитата(Forger @ Nov 28 2013, 20:16) *
Ради интереса я взял вот это довольно просто написанный JPEG-кодек: Jpegant.
Так вот. в пределе выходит 25fps.
Ради интереса попробовал включить RGB->YCrCb преобразование, то fps резко упало до 15.
Если покопаться в исходниках кодека и оптимизировать его под Cortex-M4F, то, я уверен, что fps можно еще поднять на несколько кадров.

отличный результат,
значит для блэкфина jpeg, что дают AD, действительно довольно индусский и там, наверное, тоже есть что улучшить.
Forger
Цитата(_pv @ Nov 28 2013, 17:30) *
отличный результат,

Спасибо,
Правда, я еще не проверял JPEG-декодером, все ли верно было сжато...
Rst7
Я тут выкладывал когда-то JPEG-кодер, прилично оптимизированный. На ARM7 некую среднепотолочную ч/б картинку 320 на 240 ужимало за 4.3 миллиона тактов. На Cortex-M3 будет заметно веселее.
Forger
Цитата(Rst7 @ Nov 28 2013, 19:59) *
Я тут выкладывал когда-то JPEG-кодер, прилично оптимизированный.

Очень интересно глянуть!
Цитата
На ARM7 некую среднепотолочную ч/б картинку 320 на 240 ужимало за 4.3 миллиона тактов. На Cortex-M3 будет заметно веселее.

А на Cortex-M4F еше быстрее ))
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.