|
Скорость декодирования JPEG |
|
|
|
Mar 11 2014, 05:43
|
Группа: Участник
Сообщений: 14
Регистрация: 25-12-13
Пользователь №: 79 787

|
Добрый день. Возникла проблема со скоростью декодирования JPEG. Размеры изображений 1280x800 (100kb). Прикрутил к проекту библиотеку libjpeg. Работает, но очень медленно (~ 1 кадр в сек) Делаю все следующим образом... libjpeg.hCODE typedef enum _EJpegInput { /** error/unspecified */ JPG_DATA_UNKNOWN,
/** monochrome */ JPG_DATA_GRAYSCALE,
/** red/green/blue */ JPG_DATA_RGB,
/** Y/Cb/Cr (also known as YUV) */ JPG_DATA_YCbCr,
/** C/M/Y/K */ JPG_DATA_CMYK,
/** Y/Cb/Cr/K */ JPG_DATA_YCCK } EJpegInput;
typedef enum _EJpegMethod { /** slow but accurate integer algorithm */ JPG_METHOD_ISLOW, /** faster, less accurate integer method */ JPG_METHOD_IFAST, /** floating-point: accurate, fast on fast HW */ JPG_METHOD_FLOAT } EJpegMethod;
typedef struct _SJPEGData { // Source uint8_t* pucSrc; uint32_t dwSrcLength;
// Destination uint8_t* pucDst; uint32_t dwDstLength;
// Dimensions uint32_t dwHeight; uint32_t dwWidth; uint32_t dwBPP;
// JPEG algo parameters uint32_t dwQuality; EJpegInput eInput; EJpegMethod eMethod;
uint32_t (*cbk)( uint8_t*, uint32_t, uint32_t, uint32_t); } SJpegData;
typedef struct IMAGE_DATA { unsigned char *pixels; long len; long width; long height; }ImageData;
/*------------------------------------------------------------------------------ * Exported functions *------------------------------------------------------------------------------*/
extern uint32_t JpegData_Init( SJpegData* pData ); extern uint32_t JpegData_SetSource( SJpegData* pData, uint8_t* pucSrc, uint32_t dwSrcLength );
extern uint32_t JpegData_SetDestination( SJpegData* pData, uint8_t* pucDst, uint32_t dwDstLength ); extern uint32_t JpegData_SetDimensions( SJpegData* pData, uint32_t dwWidth, uint32_t dwHeight, uint32_t dwBPP ); extern uint32_t JpegData_SetParameters( SJpegData* pData, uint32_t dwQuality, EJpegInput eInput, EJpegMethod eMethod ); extern uint32_t JpegData_SetCallback( SJpegData* pData, uint32_t (*cbk)( uint8_t*, uint32_t, uint32_t, uint32_t )); extern uint32_t ijg_compress( SJpegData* pData ); extern uint32_t ijg_compress_raw_no_padding( SJpegData* pData ); extern uint32_t ijg_decompress( SJpegData* pData ); libjpeg.cCODE // Функция декодирования extern uint32_t ijg_decompress(SJpegData* pData) { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; uint32_t dwSourceLength; int row_stride; long counter=0; JSAMPROW aLines[2]; assert( pData != NULL ); cinfo.err=jpeg_std_error( &jerr ); jpeg_create_decompress( &cinfo ); dwSourceLength=pData->dwSrcLength; jpeg_mem_src( &cinfo, (uint8_t*)pData->pucSrc, dwSourceLength ); jpeg_read_header( &cinfo, TRUE ); cinfo.dct_method = pData->eMethod; jpeg_start_decompress( &cinfo ); row_stride = cinfo.output_width * cinfo.output_components;
imageData = malloc(sizeof(ImageData)); imageData->width = cinfo.output_width; imageData->height = cinfo.output_height; imageData->len = cinfo.output_width * cinfo.output_height * cinfo.output_components; imageData->pixels = malloc(imageData->len); memset(imageData->pixels, 0, imageData->len);
aLines[0] = (JSAMPROW)malloc(sizeof(JSAMPLE) * row_stride); for (;cinfo.output_scanline < cinfo.image_height;) { jpeg_read_scanlines( &cinfo, aLines, 1 ); memcpy(imageData->pixels+counter, aLines[i], row_stride); counter += row_stride; } (*pData->cbk)(imageData->pixels, imageData->len, imageData->width, imageData->height); jpeg_finish_decompress( &cinfo ); jpeg_destroy_decompress( &cinfo ); free(imageData->pixels); free(imageData); free(aLines[0]); return 0; } main.cКод SJpegData pData; ...... JpegData_Init(&pData); JpegData_SetSource(&pData, (uint8_t*)data, len); JpegData_SetDimensions(&pData, 1280, 800, 24); JpegData_SetParameters(&pData, 12, JPG_DATA_YCbCr, JPG_METHOD_IFAST); JpegData_SetCallback(&pData, &DataImage); ijg_decompress(&pData);
Сообщение отредактировал IgorKossak - Mar 11 2014, 06:11
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
|
|
|
|
|
Mar 11 2014, 05:53
|
Группа: Участник
Сообщений: 14
Регистрация: 25-12-13
Пользователь №: 79 787

|
OK, scifi. Скажите, как понять быстро это или медленно. CPU SAMA5D3
В настройках декодера может какие-то ньюансы есть?
|
|
|
|
|
Mar 11 2014, 06:42
|
Группа: Участник
Сообщений: 14
Регистрация: 25-12-13
Пользователь №: 79 787

|
Кэши включены Код #if defined (ddram) MMU_Initialize((uint32_t *)0x30C000); CP15_EnableMMU(); CP15_EnableIcache(); CP15_EnableDcache(); #endif Если поставить linux с примером, то в браузере того самого примера отрисовка идет с приличной скоростью. (IP камера) У меня приложение без операционной системы. Данные с камеры получаю с хорошей скоростью, отрисовка на экране тоже быстро, а вот декодирование... Как тогда из под линукса это все быстро отрисовывается. Если я правильно понимаю, то в линуксе так же производится декодирование в RGB, ибо как иначе на экранчик все это вывести?
|
|
|
|
|
Mar 11 2014, 07:58
|
Группа: Участник
Сообщений: 14
Регистрация: 25-12-13
Пользователь №: 79 787

|
DpInRock, камера передает отдельные JPEGи, используя заголовки и разделители для каждого кадра. Но это не mjpeg. Здесь я разбираю посылку и выделяю из нее сам кадр. На этом этапе проблем нет, ~15 кадров в секунду, что вполне достаточно. Я сам обрабатываю каждый байт полученый с камеры, поэтому никаких ключевых кадров здесь быть не может. Так же нет никакого межкадрового сжатия и прочих плюшек mjpeg
Друзья, может какой-то декодер другой посоветуете? Сначало пробовал picjpeg. Там вообще все уныло. Или какой-то принципиально другой подход. Я имею в памяти 100-150 kb jpega. Мне нужно вывести его на экран, понимающий формат RGB, и делать это надо хотя бы 10 раз в секунду.
|
|
|
|
|
Mar 11 2014, 08:08
|

Гуру
     
Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515

|
MJEG - это РОВНО передача КАЖДОГО кадра в формате JPEG. Без ничего лишнего.
Камера обычно настраивается. Разрешение, кодировка. У меня декодер урезанный и оптимизированный прямо для моего личного экрана. Т.е. вырезано все, оптимизировано все.
И чисто по ИМХО - любые другие способы сжатия - они лучше в плане быстродействия, хотя и сложнее. Кстати, не так давно товарищу помогал как раз в линуксе на гигагерцовом проце наладить камеру, правда, USB. Вот еще больший отстой увидел... И как бы не удивился.
А вот тут раз вы говорите, что линукс бодро рисует, то у меня сомнение и закралось. В типе кодировки.(Т.е. вы настраиваете на джпег, а линукс не будь дураком - на что-то более нормальное).
Сообщение отредактировал DpInRock - Mar 11 2014, 08:10
--------------------
On the road again (Canned Heat)
|
|
|
|
|
Mar 11 2014, 08:24
|
Группа: Участник
Сообщений: 14
Регистрация: 25-12-13
Пользователь №: 79 787

|
jcxz, а я разве не так делаю сейчас. Памяти, вот посмотрите... SAMA5D3Цитата У меня декодер урезанный и оптимизированный прямо для моего личного экрана. Т.е. вырезано все, оптимизировано все. Т.е вы работаете с изображениями намного меньше моего? Если я запрашиваю с камеры область 640x400, то декодирование одного кадро проходит за 90 ms, т.е примерно 10 кадров я получаю. Вот я и пытаюсь понять, аппаратные это ограничения, или же программные.
|
|
|
|
|
Mar 11 2014, 10:01
|

Гуру
     
Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515

|
Цитата проходит за 90 ms, Вот это похоже на правду. Т.е. - на мой взгляд - нормально. Скорее всего, улучшить можно, но не кардинально (не меняя кодировки кадра). (У меня разрешение меньше, но на декодирование и отображение я выделял только 1\4 ресурсов 400 мегагерцового процессора. Хотя и камера как таковая была так себе. Да и USB - FS только.).
Сообщение отредактировал DpInRock - Mar 11 2014, 10:04
--------------------
On the road again (Canned Heat)
|
|
|
|
|
Mar 11 2014, 13:14
|
Группа: Участник
Сообщений: 14
Регистрация: 25-12-13
Пользователь №: 79 787

|
Может быть TFT дисплеи с аппаратными JPEG декодерами бывают? Кто-нибудь работал с такими?
|
|
|
|
|
Mar 12 2014, 00:04
|
Группа: Участник
Сообщений: 14
Регистрация: 25-12-13
Пользователь №: 79 787

|
Цитата 1280x800 должен бы уложится в 360мс, а не секунду. Да, Вы правы, так и есть. Декодируется за 310 ms. Есть тормоза в другом мест. Но, это только 3 кадра в сек ( Друзья, объясните, пожалуйста, как работают в таком случае фоторамки. Первый попавшийся пример Там и экран 800x600, и поддержка mjpeg. У меня 800x600 декодируется ~180 ms. Неужели рамка отображает 5-6 кадров в сек?
|
|
|
|
|
Mar 12 2014, 00:24
|
Гуру
     
Группа: Свой
Сообщений: 3 106
Регистрация: 18-04-05
Пользователь №: 4 261

|
Цитата(Александр П. @ Mar 11 2014, 12:24)  jcxz, а я разве не так делаю сейчас. Памяти, вот посмотрите... SAMA5D3Если я запрашиваю с камеры область 640x400, то декодирование одного кадро проходит за 90 ms, т.е примерно 10 кадров я получаю. Вот я и пытаюсь понять, аппаратные это ограничения, или же программные. BF533 тратит на декодирование каждого JPEG пикселя в среднем 74.3 такта процессора. Для процессора с частотой 533 МГц и кадра размером 1280*800 это дает среднее время декодирования кадра: 1280*800*74.3/533e6 = 0.14 сек. Процессор SAMA5D3, как я полагаю, должен давать примерно такие же результаты, так что получить с этим процессором 10 кадров в секунду будет, видимо, невозможно.
|
|
|
|
|
Mar 12 2014, 05:22
|

Гуру
     
Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515

|
Цитата NEON должен немного помочь. У SAM5 нет неона. Цитата Нам удалось ускорить в одном проекте библиотеку декодирования JPEG в 15!!! раз. Это просто говорит о качестве библиотеки. Не более.
--------------------
On the road again (Canned Heat)
|
|
|
|
|
Mar 12 2014, 05:35
|
Группа: Участник
Сообщений: 14
Регистрация: 25-12-13
Пользователь №: 79 787

|
Спасибо за ответы. Да, NEONа нет на SAMA5D3. Цитата Возможно ускорение, если декодировать самому каждый блок 8х8 напрямую в видеопамять. В библиотечных декодерах данные несколько раз перекопируются и перетасовываются. Нам удалось ускорить в одном проекте библиотеку декодирования JPEG в 15!!! раз. _4afc_, а какую библиотеку Вы правили? Цитата Это просто говорит о качестве библиотеки. Не более. DpInRock, Вы полагаете с libjpeg такой фокус не пройдет? Друзья, как вы считаете, получу ли я желаемый результат, если буду запрашивать с камеры H.264 и декодировать его?
|
|
|
|
|
Mar 12 2014, 07:13
|
Частый гость
 
Группа: Участник
Сообщений: 190
Регистрация: 7-11-07
Из: С-Петербург
Пользователь №: 32 134

|
Цитата Древние КПК на 400 мегагерцовых процессорах... Они работали с разрешением 320х240 и то притормаживали.
|
|
|
|
|
Mar 12 2014, 08:33
|

Профессионал
    
Группа: Свой
Сообщений: 1 262
Регистрация: 13-10-05
Из: Санкт-Петербург
Пользователь №: 9 565

|
Цитата(Александр П. @ Mar 12 2014, 08:35)  _4afc_, а какую библиотеку Вы правили? Было взято 3 исходника: Чеха, Китайца и jpegsr8b. На чехе отработали ввод вывод. Затем расписали jpegsr8b убрав лишние if на те форматы, что наша камера не генерила, расписали DCT чтоб компилился без стека и ввод/вывод был в ОЗУ камня. Насколько я помню от китайцев был какой-то толк в уменьшении количества умножений в DCT. Конкретно jpegsr8b - ускорился в 12.5 раз, а общее ускорение от Чеха до релиза - 15.5 раз.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|