Arhn - архитектура программирования

Быстрое преобразование BGR BufferedImage в YUV с использованием FFMpeg

Я хотел преобразовать TYPE_3BYTE_BGR BufferedImage в Java в yuv, используя функцию sws_scale FFMpeg через JNI. Сначала я извлекаю данные своего изображения из BufferedImage как

    byte[] imgData = ((DataBufferByte) myImage.getRaster().getDataBuffer()).getData();

    byte[] output = processImage(toSend,0);     

Затем я передаю его функции processImage, которая является нативной функцией. Сторона С++ выглядит так:

JNIEXPORT jbyteArray JNICALL Java_jni_JniExample_processData
  (JNIEnv *env, jobject obj, jbyteArray data, jint index)
{

    jboolean isCopy;
    uint8_t *test  = (uint8_t *)env->GetPrimitiveArrayCritical(data, &isCopy);
    uint8_t *inData[1]; // RGB24 have one plane
    inData[0] = test;


SwsContext * ctx = sws_getContext(width,height,AV_PIX_FMT_BGR24, (int)width, (int)width,
        AV_PIX_FMT_YUV420P, 0, 0, 0, 0);

    int lumaPlaneSize = width *height;
    uint8_t *yuv[3];

    yuv[0] = new uint8_t[lumaPlaneSize];
    yuv[1] = new uint8_t[lumaPlaneSize/4];
    yuv[2] = new uint8_t[lumaPlaneSize/4];

    int inLinesize[1] = { 3*nvEncoder->width }; // RGB stride
    int outLinesize[3] = { 3*width ,3*width ,3*width }; // YUV stride

    sws_scale(ctx, inData, inLinesize, 0, height , yuv, outLinesize);

Однако после запуска кода я получаю предупреждение: [swscaler @ 0x7fb598659480] Warning: data is not aligned! This can lead to a speedloss, everything crashes., и все вылетает на последней строке. Правильно ли я делаю все, что касается передачи правильных аргументов в sws_scale? (особенно шаги).

Обновление: здесь была отдельная ошибка: SwsContext * ctx = sws_getContext(width,height,AV_PIX_FMT_BGR24, (int)width, (int)width,0,NULL,NULL,NULL), которую следует изменить на: SwsContext * ctx = sws_getContext(width,height,AV_PIX_FMT_BGR24, (int)height, (int)width,0,NULL,NULL,NULL)


Ответы:


1

Первая проблема, которую я вижу - неправильные шаги для выходного изображения:

yuv[0] = new uint8_t[lumaPlaneSize];
yuv[1] = new uint8_t[lumaPlaneSize/4];
yuv[2] = new uint8_t[lumaPlaneSize/4];

int inLinesize[1] = { 3*nvEncoder->width }; // RGB stride
int outLinesize[3] = { 3*width ,3*width ,3*width }; // YUV stride
//                     ^^^^^^^  ^^^^^^^  ^^^^^^^

Выделенные плоскости недостаточно велики для пройденных шагов. YUV420 использует один байт для каждого канала, поэтому 3 является избыточным и приводит к нарушению границы. due rescaler пропускает много места при переходе к следующей строке. Затем фактическая ширина цветности составляет половину ширины яркости, поэтому, если вы хотите плотно упакованные плоскости яркости и цветности без пробелов на концах строк, используйте следующее:

int outLinesize[3] = { width , width / 2 , width / 2 }; // YUV stride

Размеры выделений остаются прежними.

01.08.2016
  • Спасибо за ваш ответ, однако у меня все еще есть некоторые проблемы. Если я настрою шаги на yuv[1] = new uint8_t[lumaPlaneSize/2]; и yuv[1] = new uint8_t[lumaPlaneSize/2]; , кажется, все идет нормально с предложенным вами outputLinesize. За исключением случаев, когда я записываю вывод в файл: fwrite(yuv[0], 1, lumaPlaneSize, fp); fwrite(yuv[1], 1, lumaPlaneSize/4, fp); fwrite(yuv[2], 1, lumaPlaneSize/4, fp); Кажется, что изображение масштабировано и неполно. Я меняю на fwrite(yuv[1 and 2], 1, lumaPlaneSize/2, fp); то изображение вообще плохое Что делать? 02.08.2016
  • Как именно выглядит неполное изображение? 03.08.2016
  • до: postimg.org/image/gr93ykns1 после: postimg.org/image/f0mg9dyvb 03.08.2016
  • Я предполагаю, что пятый параметр sws_getContext() должен быть высотой, а не шириной. 03.08.2016
  • какой грех... Большое спасибо! 03.08.2016

  • 2

    Глядя на исходный код, в частности, на строку 321, вы получаете предупреждающее сообщение, если ваша система поддерживает инструкции AVX2, а различные указатели и размеры не кратны 16. Сбой, вероятно, происходит из-за того, что массивы, которые вы передаете, inData, inLineSize и outLinesize, имеют неправильный размер. Массивы указателей должны иметь как минимум 3 элемента, а массивы шагов - 4. Где-то в sws_scale он обращается к inData[1], который находится за пределами вашего массива, что приводит к плохому указателю.

    30.07.2016
  • Массивы указателей должны иметь как минимум 3 элемента, а массивы шагов - 4... - нет, эти размеры строго определяются используемым форматом пикселей, а в случае YUV420 и буферный массив, и массив шагов должны содержать ровно 3 элемента - для Y, Cr, Cb плоскости каждая. 01.08.2016
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..