Nppi Color Conversion Issue

Я пытаюсь преобразовать кадр 3-канального упакованного rgb в nv12, используя библиотеку nvidia npp. Вот код, который у меня есть:

//cpu buffer that will hold converted data
Npp8u* converted_data = (Npp8u*)malloc(frameToWrite.getWidth());
memset(converted_data, 0, frameToWrite.getSize());

//Begin - load data and convert rgb to yuv
{
NppStatus ret = NPP_SUCCESS;
int stepSource;
Npp8u* frame = nppiMalloc_8u_C3(frameToWrite.getWidth(), frameToWrite.getHeight(), &stepSource);
cudaMemcpy2D(frame, stepSource, frameToWrite.getFrame(), frameToWrite.getSizePerRow(), frameToWrite.getWidth(), frameToWrite.getHeight(), cudaMemcpyHostToDevice);

int stepDestP1, stepDestP2, stepDestP3;
Npp8u* m_stYuvP1 = nppiMalloc_8u_C1(frameToWrite.getWidth(), frameToWrite.getHeight(), &stepDestP1);
Npp8u* m_stYuvP2 = nppiMalloc_8u_C1(frameToWrite.getWidth(), frameToWrite.getHeight(), &stepDestP2);
Npp8u* m_stYuvP3 = nppiMalloc_8u_C1(frameToWrite.getWidth(), frameToWrite.getHeight(), &stepDestP3);
int d_steps[3] = { stepDestP1, stepDestP2, stepDestP3 };
Npp8u* d_ptrs[3] = { m_stYuvP1, m_stYuvP2, m_stYuvP3 };

NppiSize ROI = { frameToWrite.getWidth(), frameToWrite.getHeight() };

if ((ret = nppiRGBToYUV_8u_C3P3R(frame, stepSource, d_ptrs, stepDestP1, ROI)) != NPP_SUCCESS)
return ERROR_CODE_NVENC_ERROR_UNKNOWN;

cudaMemcpy2D(converted_data, frameToWrite.getWidth(), m_stYuvP1, stepDestP1, frameToWrite.getWidth(), frameToWrite.getHeight(), cudaMemcpyDeviceToHost);
}

Его в основном основано на этот вопрос переполнения стека, но я подстроил его под свой случай. Как примечание стороны, frameToWrite.getSize() рассчитывается так:

mFrameSize = ((getBytesPerPixel() * mWidth) + mPaddingInBytes) * mHeight;

где getBytesPerPixel() обычно возвращается 3,

В конечном итоге мои вопросы:

  • Как мне начать извлекать преобразованные данные изображения из памяти устройства?
  • Правильно ли я передал данные неконвертированного изображения на устройство?

1

Решение

Npp8u* converted_data = (Npp8u*)malloc(frameToWrite.getWidth());
memset(converted_data, 0, frameToWrite.getSize());

Прежде всего, если вы еще не заметили, вы, вероятно, выделяете здесь немного памяти, а затем используете memset на гораздо большей области, что может вызвать нежелательное поведение.

Что касается ваших вопросов:
Трудно сказать, что вы делаете frameToWrite.getWidth() а также frameToWrite.getHeight() return — это размеры изображения или байтовые размеры? Обычно, когда вы распределяете буферы NPP, вы должны использовать байтовые измерения, например, так:
nppiMalloc_8u_C1(pixelWidth*bytesPerPixel, pixelHeight, &stepSource);

Кроме того, размер шага должен быть равен длине строки в байтах плюс заполнение в соответствии с пунктом 4.2.1 документации АЭС.

Что касается извлечения изображения из памяти, из моего личного опыта самый простой способ сделать это просто с помощью cudaMemcpy Так как npp выделяет 2D память только с виртуальным разделением, в то время как исходные данные все еще выровнены, следовательно, 1D cudaMemcpy вызова достаточно, чтобы получить данные обратно.

0

Другие решения


По вопросам рекламы [email protected]