How can I convert rgb8 to h264?


I am using ptgrey usb camera ,set format BayerRG8. And convert it to RGB8 using spinnkersdk.

I want to convert it to h264 by using NvVideoEncoder. But NvVideoEncoder just support V4L2_PIX_FMT_YUV420M.

  1. How can I convet PixelFormat_RGB8(or PixelFormat_BayerRG8) to V4L2_PIX_FMT_YUV420M.

  2. Another question, I have 260 pictures(2448 * 2048) each second. What is the best way to convert in my Xavier?

  1. If Use ffmpeg convet rgb8 to h264,can I use 7 thread? what is the efficiency?

You may utilize Nvbuffer APIs for conversion. Since hardware converter does not support RGB, you may allocate either NvBufferColorFormat_ABGR32 or NvBufferColorFormat_XRGB32 in calling NvBufferCreateEx().
1 Allocate NvBufferColorFormat_ABGR32(or NvBufferColorFormat_XRGB32) and NvBufferColorFormat_YUV420 buffers
2 Copy the RGB8 data into the RGBA buffers.
3 Do conversion though NvBufferTransform()
4 Feed YUV420 buffers to NvVideoEcoder.

There are several samples demonstrating NvBuffer APIs. Please check and try.

Thank you for reply!

I am doing just like you sayed. But I find Raw2NvBuffer to slow. need 0.048s, my picture size is 2448 * 2048 * 4. Is there any way to change that?

Please execute ‘sudo nvpmodel -m 0’ and ‘sudo jetson_clocks’ It is memcpy(copy CPU buffer to NvBuffer) and consumes certain CPU cycles.


After run “sudo /home/nvidia/” and sudo nvpmodel -m 0.
The CPU fan is running, and nvpmodel is 0. But Raw2NvBuffer is slow too.
tmB is also memcpy, and just need 3000us; But Raw2NvBuffer need 54857 us.

Finally, I find the result.
If I set NvBufferLayout_BlockLinear, Raw2NvBuffer need 54857 us.
And if i set NvBufferLayout_Pitch,Raw2NvBuffer need 6656 us.

So what is the different of NvBufferLayout_BlockLinear and NvBufferLayout_Pitch.

Raw2NvBuffer() is an easy-to-use function. For better performance, you may use other NvBuffer APIs. Please check code of DO_CPU_PROCESS option in 10_camera_recording. You can call NvBufferGetParams() and NvBufferMemMap() once in initialization and NvBufferMemUnMap() in termination. It should save certain time in mapping/unmapping memory.

Hello, DaneLLL

Sorry to trouble you again.Now I am using NvBufferGetParams and NvBufferMemMap.

My problem is mp4 color now right.

  1. How can I convert rgba8 to NvBufferColorFormat_ARGB32?
  2. rgba_buffer is from camera, 2448 * 4 * 2048, all of the ‘a’ is 0xff. But I find argb32 pitch is now width * 4, why?

Here is my code,m_argb_dmabuf_fd Color format is NvBufferLayout_Pitch.


input_params.payloadType = NvBufferPayload_SurfArray;
input_params.width = m_size.width();
input_params.height = m_size.height();
input_params.layout = NvBufferLayout_Pitch;
input_params.nvbuf_tag = NvBufferTag_NONE;
input_params.colorFormat = NvBufferColorFormat_ARGB32;
if (NvBufferCreateEx(&m_argb_dmabuf_fd, &input_params) < 0)
ORIGINATE_ERROR(“Failed to create NvBuffer.”);

memset(&trans_params_, 0, sizeof(trans_params_));
trans_params_.transform_flag = NVBUFFER_TRANSFORM_FILTER;
trans_params_.transform_filter = NvBufferTransform_Filter_Smart;

NvBufferMemMap(m_argb_dmabuf_fd, 0, NvBufferMem_Read_Write, &m_argb_dmabuf_buffer);



unsigned char * rgba_buffer = static_cast<unsigned char*>(image_info.second->GetData());

NvBufferMemSyncForCpu(m_argb_dmabuf_fd, 0, &m_argb_dmabuf_buffer);
unsigned char * ptr_buffer = (unsigned char *)m_argb_dmabuf_buffer;
for(int i = 0; i < m_argb_parm.height[0]; i++)
    int src_pos_y = i * m_argb_parm.width[0] * 4;
    int des_pos_y = i * m_argb_parm.pitch[0];
    for (int j = 0; j < m_argb_parm.width[0]; ++j) {
        int pos_x = j * 4;
        ptr_buffer[des_pos_y + pos_x] = rgba_buffer[src_pos_y + pos_x + 3];//a
        ptr_buffer[des_pos_y + pos_x + 1] = rgba_buffer[src_pos_y + pos_x + 0];//r
        ptr_buffer[des_pos_y + pos_x + 2] = rgba_buffer[src_pos_y + pos_x + 1];//g
        ptr_buffer[des_pos_y + pos_x + 3] = rgba_buffer[src_pos_y + pos_x + 2];//b
NvBufferMemSyncForDevice(m_argb_dmabuf_fd, 0, &m_argb_dmabuf_buffer);


This code is the same error.

unsigned char * rgba_buffer = static_cast<unsigned char*>(image_info.second->GetData());
int size = (int)image_info.second->GetBufferSize();

// rgba to argb
memcpy(rgba_buffer + 1, rgba_buffer, size - 1);
rgba_buffer[0] = 0xff;

Raw2NvBuffer(rgba_buffer, 0, 2448, 2048, m_argb_dmabuf_fd);

For NvBufferColorFormat_ARGB32, the order should be

B G R A B G R A B G R A ...

One pixel is 4-byte BGRA, so pitch=width*4

Suggest you try NvBufferColorFormat_ABGR32

Thank you.

Yes, I used NvBufferColorFormat_ABGR32, it is same to My RGBA8, just need to copy like the following code.

unsigned char * rgba_buffer = static_cast<unsigned char*>(image_info.second->GetData());

Raw2NvBuffer(rgba_buffer, 0, 2448, 2048, m_argb_dmabuf_fd);