Text flashes and then disappears when use nvosd to overlay text in a gstreamer video

Hi,
I make a gstreamer plugin with nvosd lib to overlay text on the video. While when I try to overlay text in a video stream which selected from several video streams using gst-input-selector plugin, the text would flash several seconds and then disappear. The Error is

NvMapMemCacheMaint:1075334668 failed [14]

And look the kernal log, it outputs something likes:

WARNING: All NvMap Allocations must have a tag to identify the subsystem allocating memory.Please pass the tag to the API call NvRmMemHanldeAllocAttr() or relevant.

Any help to correct this would be appreciated, thanks.

Hi,
We would need your help to share us steps to reproduce the issue first. Or you may try nvdsosd plugin and see if it works fine.

Do you use Jetpack 4 or Jetpack 5 release? Please also share the release version you are using.

Hi,
I use Jetpack 4.6 [L4T 32.6.1]. And the issue happens when I try to use one nvosd_ctx for several dmabuf_fd (more than 4 fds) use the nvosd_put_text api :

int nvosd_put_text(void *nvosd_ctx, NvOSD_Mode mode, int fd, int num_strings,
NvOSD_TextParams *text_params_list);

So whether it caused this issue. Anyway, I will try to create the same amount of nvosd_ctx as the dmabuf_fds to check whether it works, thanks.

Hi,
I try to create more nvosd_ctx for more dmabuf_fd, but it seems not works. And I notice that the vic_freq is nearly 99%(usually 95%~99%).

Hi,
Please call NvBufferMemSyncForDevice() after nvosd_put_text() for a try.

Hi,
I try call NvBufferMemSyncForDevice but it doesn’t work. The part of my code is

if (!gst_buffer_map(inbuf, &inmap, GST_MAP_WRITE)) {
            GST_ERROR_OBJECT(osd, "input buffer mapinfo failed");
            goto error;
        }
        ret = ExtractFdFromNvBuffer(inmap.data, &dmabuf_fd);
        if (ret != 0) {
            GST_ERROR_OBJECT(osd, "ExtractFdFromNvBuffer failed");
            gst_buffer_unmap(inbuf, &inmap);
            goto error;
        }
        NvBufferParams src_param;
        void *virtualip_data_addr;
        unsigned int plane = 0;
        ret = NvBufferGetParams (dmabuf_fd, &src_param);
        if (ret != 0)
        {
            GST_ERROR_OBJECT(osd, "Get Params failed");
            gst_buffer_unmap(inbuf, &inmap);
            goto error;
        }
        nvosd_put_text(osd->nvosd_ctx,
                              MODE_GPU,
                              dmabuf_fd,
                              1,
                              &osd->text_params);
        for (; plane < src_param.num_planes ; ++plane) {
            ret = NvBufferMemMap (dmabuf_fd, plane, NvBufferMem_Write, &virtualip_data_addr);
            if (ret == 0) {
                NvBufferMemSyncForDevice (dmabuf_fd, plane, &virtualip_data_addr);
            }
            NvBufferMemUnMap (dmabuf_fd, plane, &virtualip_data_addr);
        }
    
        gst_buffer_unmap(inbuf, &inmap);

The code will be called for different fds ( e.g. four different dmabuf_fds will input into the function ) in a thread. If this is the correct way to call jetson multimedia api, or what I can do to call the apis correctly. Thanks.

More details, when I use diffrent camera sources (hdmi + ipc) as input , this issue always happens. And when I use one type of cameras ( e.g. three ipc cameras ) as input, sometimes it works well and sometimes the text disappears .

Hi,
For further check, we would need your help to share a test code(better to be based on 02_video_dec_cuda) for replicating the issue. So that we can check further.

Another solution is to use cairo APIs to put tandext and then call NvBufferMemSyncForDevice(). May refer to
Tx2-4g r32.3.1 nvivafilter performance - #16 by DaneLLL

Can get CPU pointer to NvBuffer by calling NvBufferMemMap()

Hi,
Thank you for your timely reply. I will try to construct a test code for replicating the issue. And I will try the solution of cairo.
And as I say before, the vic_freq is too high, means that I do too much video format transformation. Because textovley only support RGBA format, and the video format in my case must be I420, so I want to transform I420->RGBA, textoverlay and then RGBA->I420 using cuda. I know I can get egl image from NvBuffer by NvEGLImageFromFd(), and then map it to cuda memory. In my opinion, the I420 buffer and the RGBA buffer in cuda/NvBuffer/EglImage have different byte size. I must allocate a new buffer for transforming I420 to RGBA (or RGBA to I420). There are two questions:

  1. How can I copy the new allocated cuda memory to the NvBuffer (dmabuf fd) ?
  2. Whether I must call NvBufferCreateEx to create a new NvBuffer for accepting transformed cuda data ?

Thanks.

Hi,
If VIC is always heavy in th euse-case, please refer t the steps to enable it always at maximum clock:
Nvvideoconvert issue, nvvideoconvert in DS4 is better than Ds5? - #3 by DaneLLL

You can get CUDA pointer of an NvBuffer by calling:

NvEGLImageFromFd();
cuGraphicsEGLRegisterImage();
cuGraphicsResourceGetMappedEglFrame();

And call cudaMemcpy() to copy the data.

If you need to use hardware encoder or renderer, the frame data has to be in NvBuffer.

Hi,
Sorry for my late response. I try to build a gstreamer plugin and a test code for rebuild the issue.

The source code and Makefile of the plugin is as follows :
gstmyosd.c (14.6 KB)
gstmyosd.h (1.8 KB)
Makefile (2.3 KB)

And the test code is as follows with the compiler command gcc input-selector.c -o input-selector pkg-config --cflags --libs gstreamer-1.0``:
input-selector.c (3.5 KB)

The test steps :

  1. input o to run the pipeline;
  2. input r to selector the new pad;

And the issue will happen and output the error NvMapMemCacheMaint:1075334668 failed [14]

Thank you.

Sorry for the late response, have you managed to get issue resolved or still need the support? Thanks

HI,
I try the solution that to use cairo APIs to put text and then call NvBufferMemSyncForDevice() then it works with some cost of CPU. While it is better to fix the issue when use nvosd api.
Thanks.

Hi,
cairo APIs should work same as nvosd_put_text() since we support only MODE_CPU:

/**
 * Overlays clock and given text at given location on a buffer.
 *
 * To overlay the clock, you must set clock params using
 * nvosd_set_clock_params().
 * You must ensure that the length of @a text_params_list is at least
 * @a num_strings.
 *
 * @note Currently only #MODE_CPU is supported. Specifying other modes wil have
 * no effect.
 *
 * @param[in] nvosd_ctx A pointer to NvOSD context.
 * @param[in] mode Mode selection to draw the text.
 * @param[in] fd DMABUF FD of buffer on which text is to be overlayed.
 * @param[in] num_strings Number of strings to be overlayed.
 * @param[in] text_params_list A pointer to an array of NvOSD_TextParams
 *            structure for the clock and text to be overlayed.
 *
 * @returns 0 for success, -1 for failure.
 */
int nvosd_put_text(void *nvosd_ctx, NvOSD_Mode mode, int fd, int num_strings,
        NvOSD_TextParams *text_params_list);

MODE_GPU does not work. We may miss to return error when the mode is not supported.