Segmentation Fault in Decoder Thread When using NvDsMeta on Live Stream

Please provide complete information as applicable to your setup.

• Hardware Platform: RTX 4070
• DeepStream Version: 7.1
• TensorRT Version: 10.7.0
• NVIDIA GPU Driver Version: 570.133.07
• Issue Type: Questions / Bugs

Hello, I have encountered a curious situation with Deepstream, where the application exits with SEGMENTATION FAULT error after a few minutes of processing. The situation is quite rare, as it does not happen often and only on certain live streams.

I suspect the segmentation fault occurs in the nvv4l2decoder element due to the stack trace from gdb (this has been consistent over 20+ trials)

Thread 47 "dec:src" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fff6d600640 (LWP 1610139)]
0x00007ffff7e79ebc in gst_buffer_copy_into () from /lib/x86_64-linux-gnu/libgstreamer-1.0.so.0
(gdb) bt
#0  0x00007ffff7e79ebc in gst_buffer_copy_into () at /lib/x86_64-linux-gnu/libgstreamer-1.0.so.0
#1  0x00007ffff612e106 in  () at /usr/lib/x86_64-linux-gnu/gstreamer-1.0/deepstream/libgstnvvideo4linux2.so
#2  0x00007ffff7ee31d7 in  () at /lib/x86_64-linux-gnu/libgstreamer-1.0.so.0
#3  0x00007ffff7d0ea34 in g_thread_pool_thread_proxy (data=<optimized out>) at ../glib/gthreadpool.c:350
#4  0x00007ffff7d07a91 in g_thread_proxy (data=0x7fff10001350) at ../glib/gthread.c:831
#5  0x00007ffff7694ac3 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#6  0x00007ffff7726850 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81

Another interesting observation is that:

  • I have encountered this error only if there is some NvDsMeta added before the decoder element.
  • If there are no NvDsMeta attached to the buffer before decoder, this does not happen

This is the code I have created to demonstrate the issue (it uses mainly code from the Deepstream examples)

#include <string>

#include <glib.h>
#include <gst/gst.h>
#include <gst/gstbuffer.h>
#include <gstnvdsmeta.h>
#include <iostream>
#include <memory>

NvDsMetaType metaType = nvds_get_user_meta_type("EXAMPLE.PTS_ADJUSTED.META");
#define NVDS_DECODER_GST_META_EXAMPLE (nvds_get_user_meta_type("NVIDIA.DECODER.GST_USER_META"))

gint frame_number = 0;
gint parsed_frame_number = 0;

class PtsAdjustedMeta {
public:
    guint i1;
    guint i2;
    gboolean flag;
};


static void meta_release_func(gpointer data, gpointer user_data) {
    PtsAdjustedMeta *decoder_meta = (PtsAdjustedMeta *) data;
    if (decoder_meta == nullptr) {
        return;
    }
    g_free(decoder_meta);
}

static gpointer meta_copy_func(gpointer data, gpointer user_data) {
    // PtsAdjustedMeta *src_decoder_meta = (PtsAdjustedMeta *) data;
    // if (src_decoder_meta == nullptr) {
    // return nullptr;
    // }

    // PtsAdjustedMeta *dst_decoder_meta = new PtsAdjustedMeta(*src_decoder_meta);
    // return dst_decoder_meta;
    return nullptr;
}


static void BufferAdd(GstBuffer *buf) {
    PtsAdjustedMeta *pMeta = (PtsAdjustedMeta *) g_malloc0(sizeof(PtsAdjustedMeta));
    NvDsMeta *meta = gst_buffer_add_nvds_meta(buf, pMeta, nullptr, meta_copy_func, meta_release_func);

    meta->meta_type = metaType;
    meta->gst_to_nvds_meta_transform_func = nullptr;
    meta->gst_to_nvds_meta_release_func = nullptr;
}


typedef struct _NvDecoderMeta {
    guint frame_type;
    guint frame_num;
    gboolean dec_err;
} NvDecoderMeta;

/* gst meta copy function set by user */
static gpointer decoder_meta_copy_func(gpointer data, gpointer user_data) {
    NvDecoderMeta *src_decoder_meta = (NvDecoderMeta *) data;
    NvDecoderMeta *dst_decoder_meta = (NvDecoderMeta *) g_malloc0(sizeof(NvDecoderMeta));
    memcpy(dst_decoder_meta, src_decoder_meta, sizeof(NvDecoderMeta));
    return (gpointer) dst_decoder_meta;
}

/* gst meta release function set by user */
static void decoder_meta_release_func(gpointer data, gpointer user_data) {
    NvDecoderMeta *decoder_meta = (NvDecoderMeta *) data;
    if (decoder_meta) {
        g_free(decoder_meta);
        decoder_meta = NULL;
    }
}

/* gst to nvds transform function set by user. "data" holds a pointer to NvDsUserMeta */
static gpointer decoder_gst_to_nvds_meta_transform_func(gpointer data, gpointer user_data) {
    NvDsUserMeta *user_meta = (NvDsUserMeta *) data;
    NvDecoderMeta *src_decoder_meta = (NvDecoderMeta *) user_meta->user_meta_data;
    NvDecoderMeta *dst_decoder_meta = (NvDecoderMeta *) decoder_meta_copy_func(src_decoder_meta, NULL);
    return (gpointer) dst_decoder_meta;
}

/* release function set by user to release gst to nvds transformed metadata.
 * "data" holds a pointer to NvDsUserMeta */
static void decoder_gst_nvds_meta_release_func(gpointer data, gpointer user_data) {
    NvDsUserMeta *user_meta = (NvDsUserMeta *) data;
    NvDecoderMeta *decoder_meta = (NvDecoderMeta *) user_meta->user_meta_data;
    decoder_meta_release_func(decoder_meta, NULL);
}


static GstPadProbeReturn nvdecoder_src_pad_buffer_probe_basic(GstPad *pad, GstPadProbeInfo *info, gpointer u_data) {
    GstBuffer *buf = (GstBuffer *) info->data;
    NvDsMeta *meta = NULL;

    NvDecoderMeta *decoder_meta = (NvDecoderMeta *) g_malloc0(sizeof(NvDecoderMeta));
    if (decoder_meta == NULL) {
        exit(-1);
    }
    /* Add dummy metadata */
    decoder_meta->frame_type = (frame_number % 3);
    decoder_meta->frame_num = frame_number++;
    decoder_meta->dec_err = ((frame_number % 4) / 3);

    /* Attach decoder metadata to gst buffer using gst_buffer_add_nvds_meta() */
    meta = gst_buffer_add_nvds_meta(buf, decoder_meta, NULL, decoder_meta_copy_func, decoder_meta_release_func);

    /* Set metadata type */
    meta->meta_type = (GstNvDsMetaType) NVDS_DECODER_GST_META_EXAMPLE;

    /* Set transform function to transform decoder metadata from Gst meta to
   * nvds meta */
    meta->gst_to_nvds_meta_transform_func = decoder_gst_to_nvds_meta_transform_func;

    /* Set release function to release the transformed nvds metadata */
    meta->gst_to_nvds_meta_release_func = decoder_gst_nvds_meta_release_func;

    g_print("GST Dec Meta attached with gst decoder output buffer for Frame_Num = %d\n", decoder_meta->frame_num);
    g_print(
        "Attached decoder Metadata: frame type = %d, frame_num = %d decode_error_status = %d\n",
        decoder_meta->frame_type,
        decoder_meta->frame_num,
        decoder_meta->dec_err
    );

    return GST_PAD_PROBE_OK;
}

static GstPadProbeReturn nvdecoder_src_pad_buffer_probe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data) {
    GstBuffer *buf = (GstBuffer *) info->data;
    BufferAdd(buf);
    g_print("Added meta: %lu\n", buf->pts);
    return GST_PAD_PROBE_OK;
}

int main(int argc, char *argv[]) {
    gst_init(&argc, &argv);

    std::string uri = "rtsp://192.168.5.10:8554/mystream";

    // Construct the pipeline string
    std::string pipelineDesc = g_strdup_printf(
        "urisourcebin uri=%s ! parsebin name=parser !  identity name=i ! nvv4l2decoder name=dec ! "
        "nveglglessink sync=0 ",
        uri.c_str()
    );

    // Parse and create the pipeline
    GError *error = nullptr;
    GstElement *pipeline = gst_parse_launch(pipelineDesc.c_str(), &error);

    GstElement *identity = gst_bin_get_by_name(GST_BIN(pipeline), "i");
    GstPad *identitySrc = gst_element_get_static_pad(identity, "src");
    gst_pad_add_probe(identitySrc, GST_PAD_PROBE_TYPE_BUFFER, nvdecoder_src_pad_buffer_probe_basic, nullptr, nullptr);


    if (not pipeline) {
        g_printerr("Failed to create pipeline: %s\n", error->message);
        g_clear_error(&error);
        return -1;
    }

    gst_element_set_state(pipeline, GST_STATE_PLAYING);

    GstBus *bus = gst_element_get_bus(pipeline);
    GstMessage *msg =
        gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, (GstMessageType) (GST_MESSAGE_ERROR | GST_MESSAGE_EOS));

    // Handle message
    if (msg != nullptr) {
        GError *err;
        gchar *debug_info;

        switch (GST_MESSAGE_TYPE(msg)) {
            case GST_MESSAGE_ERROR:
                gst_message_parse_error(msg, &err, &debug_info);
                g_printerr("Error received: %s\nDebug: %s\n", err->message, debug_info);
                g_clear_error(&err);
                g_free(debug_info);
                break;
            case GST_MESSAGE_EOS:
                g_print("End-Of-Stream reached.\n");
                break;
            default:
                break;
        }
        gst_message_unref(msg);
    }

    // Cleanup
    gst_object_unref(bus);
    gst_element_set_state(pipeline, GST_STATE_NULL);
    gst_object_unref(pipeline);
    return 0;
}

The problem here is that I am not able to provide an input to replicate this exact behavior, as the problematic video is in fact a live stream. I understand that this is inconvenient, but I was unable to provide any alternative (i.e. recording the video stream using ffmpeg and using the file as the input did not replicate the problem).

However I believe it is worth to provide the code and the stack traces, and some insights about the situations in which it happens, as i believe that even with some corrupted frames (which I expect is the case), the application should raise a warning or an exception and end gracefully, rather than raising a segmentation fault.

If there is any more info (i.e. gdb logs, etc.) I will be very happy to help.

Thanks,
Simon

Also adding the CMake I used to compile the program, for completeness:

cmake_minimum_required(VERSION 3.21)
project(sample_metadata LANGUAGES CXX)

set(CMAKE_CXX_FLAGS "-O0 -ggdb" )
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)

set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH ON)
find_package(PkgConfig REQUIRED)
if (NOT (PKGCONFIG_FOUND))
    message(FATAL_ERROR "Please Install PPkgConfig: CMake will Exit")
endif ()

pkg_check_modules(GST REQUIRED gstreamer-1.0 gstreamer-base-1.0 gstreamer-video-1.0)

if (NOT (GST_FOUND))
    message(FATAL_ERROR "Please Install Gstreamer Dev: CMake will Exit")
endif ()

include_directories(/opt/nvidia/deepstream/deepstream/sources/includes)
include_directories(/opt/nvidia/deepstream/deepstream/sources/gst-plugins/gst-nvdsvideotemplate/includes)
include_directories("${GST_INCLUDE_DIRS}")

link_directories(/opt/nvidia/deepstream/deepstream/lib)

set(PROJECT_LIBRARIES ${GST_LIBRARIES} nvbufsurftransform nvdsgst_helper nvdsgst_meta nvds_meta nvbufsurface nvdsbufferpool)

add_executable(sample_metadata main.cpp)
target_link_libraries(sample_metadata PUBLIC ${PROJECT_LIBRARIES})

It’s a tricky question, Based on the information you provided and the stack strace. I think this issue might be due to a memory overflow while copying metadata.

If you modify the memory layout of NvDecoderMeta, such as adding other members, will the stack strace change?

Some other tips.

1.Install gstreamer debug library( like libgstreamer1.0-0-dbgsym*) to capture function line from stack pointer.

  1. Download Driver Package (BSP) Sources from this link. Although this code is used for Jetson, but gst-nvvideo4linux2_src.tbz2 is same both on dGPU and Jetson, you can port this code to dGPU for analysis this issue.
    Jetson Linux | NVIDIA Developer

3.Use the valgrind to check memory out-of-bounds.

Please check the gstreamer version first to avoid incompatible deb packages.

Hello,

thanks, adding the debug symbols provided some very useful info to the stack trace. Out of curiosity, I have changed the layout of _NvDecoderMeta so now it looks like this:

typedef struct _NvDecoderMeta {
    guint frame_type;
    guint frame_num;
    gboolean dec_err;
    guint32 buffer[2048];

} NvDecoderMeta;

The order of the stack trace however remains the same.

#0  gst_buffer_copy_into (dest=0x7ffef0515a70, src=0x7fff0804df70, flags=<optimized out>, offset=0, size=194) at ../gst/gstbuffer.c:673
#1  0x00007ffff612e106 in ?? () from /usr/lib/x86_64-linux-gnu/gstreamer-1.0/deepstream/libgstnvvideo4linux2.so
#2  0x00007ffff7f031d7 in gst_task_func (task=0x7ffef05166c0) at ../gst/gsttask.c:384
#3  0x00007ffff7d2ea34 in g_thread_pool_thread_proxy (data=<optimized out>) at ../glib/gthreadpool.c:350
#4  0x00007ffff7d27a91 in g_thread_proxy (data=0x7fff10001350) at ../glib/gthread.c:831
#5  0x00007ffff7694ac3 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#6  0x00007ffff7726850 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81

The version of the gstreamer is 1.20.3-0ubuntu1.1, looking at the sources for gstbuffer.c, we get that the segmentation fault happens here

  if (flags & GST_BUFFER_COPY_META) {
    /* NOTE: GstGLSyncMeta copying relies on the meta
     *       being copied now, after the buffer data,
     *       so this has to happen last */
    for (walk = GST_BUFFER_META (src); walk; walk = walk->next) {
      GstMeta *meta = &walk->meta; /// <<< SEGMENTATION FAULT
      const GstMetaInfo *info = meta->info;
(gdb) info locals
meta = <optimized out>
info = <optimized out>
walk = 0x7ff90fe9a36c
bufsize = <optimized out>
region = 0

(gdb) print walk
$1 = (GstMetaItem *) 0x7ff90fe9a36c
(gdb) print walk->meta
Cannot access memory at address 0x7ff90fe9a37c
(gdb) print *walk
Cannot access memory at address 0x7ff90fe9a36c

I therefore assume that the walk variable itself points to an invalid memory address, therefore the attempt at accessing the property meta (or any other property for the matter) ends in a segmentation fault

This may be due to an abnormal stream causing an illegal pointer, You can try to port gst-nvvideo4linux2_src.tbz2 to get more information.

Although you said that dump video stream cannot reproduce the problem,I’d still like to try to reproduce the issue.

gst-launch-1.0 -e urisourcebin uri=rtsp://xxx ! queue ! parsebin ! queue ! h264parse ! mpegtsmux ! filesink location=rtsp.ts

Or you could update your driver to see if that does the trick as a workaround.Because I think it may have something to do with the hardware decoder driver.

In addition, use the following command to capture log of nvv4l2decoder

GST_DEBUG_NO_COLOR=1 GST_DEBUG=3,nvv4l2decoder:7 gst-launch-1.0 urisourcebin uri=rtsp:// ! parsebin name=parser !  identity name=i ! nvv4l2decoder name=dec ! fakesink > log.log 2>&1

I used the command to log debug info for nvv4l2decoder, however except for one decreasing timestamp in the stream, there does not seem to be any obvious problem

Attached decoder Metadata: frame type = 2, frame_num = 7070 decode_error_status = 1
0:03:57.038267998 2392092 0x7ec170001060 FIXME           rtph265depay gstrtph265depay.c:1287:gst_rtp_h265_depay_process:<rtph265depay0> Assuming DONL field is not present
0:03:57.038274183 2392092 0x7ec170001060 FIXME           rtph265depay gstrtph265depay.c:1287:gst_rtp_h265_depay_process:<rtph265depay0> Assuming DONL field is not present
0:03:57.038279930 2392092 0x7ec170001060 FIXME           rtph265depay gstrtph265depay.c:1287:gst_rtp_h265_depay_process:<rtph265depay0> Assuming DONL field is not present
0:03:57.038285546 2392092 0x7ec170001060 FIXME           rtph265depay gstrtph265depay.c:1287:gst_rtp_h265_depay_process:<rtph265depay0> Assuming DONL field is not present
0:03:57.038291006 2392092 0x7ec170001060 FIXME           rtph265depay gstrtph265depay.c:1287:gst_rtp_h265_depay_process:<rtph265depay0> Assuming DONL field is not present
0:03:57.038296952 2392092 0x7ec170001060 FIXME           rtph265depay gstrtph265depay.c:1287:gst_rtp_h265_depay_process:<rtph265depay0> Assuming DONL field is not present
0:03:57.038390110 2392092 0x7ec170001350 WARN            videodecoder gstvideodecoder.c:3158:gst_video_decoder_prepare_finish_frame:<dec> decreasing timestamp (0:03:56.513259246 < 0:03:56.546435830)
0:03:57.082928349 2392092 0x7ec170001060 FIXME           rtph265depay gstrtph265depay.c:1287:gst_rtp_h265_depay_process:<rtph265depay0> Assuming DONL field is not present
0:03:57.082948213 2392092 0x7ec170001060 FIXME           rtph265depay gstrtph265depay.c:1287:gst_rtp_h265_depay_process:<rtph265depay0> Assuming DONL field is not present
0:03:57.082956851 2392092 0x7ec170001060 FIXME           rtph265depay gstrtph265depay.c:1287:gst_rtp_h265_depay_process:<rtph265depay0> Assuming DONL field is not present
0:03:57.082964983 2392092 0x7ec170001060 FIXME           rtph265depay gstrtph265depay.c:1287:gst_rtp_h265_depay_process:<rtph265depay0> Assuming DONL field is not present
0:03:57.082972958 2392092 0x7ec170001060 FIXME           rtph265depay gstrtph265depay.c:1287:gst_rtp_h265_depay_process:<rtph265depay0> Assuming DONL field is not present
0:03:57.082985348 2392092 0x7ec170001060 FIXME           rtph265depay gstrtph265depay.c:1287:gst_rtp_h265_depay_process:<rtph265depay0> Assuming DONL field is not present
0:03:57.082993126 2392092 0x7ec170001060 FIXME           rtph265depay gstrtph265depay.c:1287:gst_rtp_h265_depay_process:<rtph265depay0> Assuming DONL field is not present
0:03:57.083000463 2392092 0x7ec170001060 FIXME           rtph265depay gstrtph265depay.c:1287:gst_rtp_h265_depay_process:<rtph265depay0> Assuming DONL field is not present
0:03:57.083012518 2392092 0x7ec170001060 FIXME           rtph265depay gstrtph265depay.c:1287:gst_rtp_h265_depay_process:<rtph265depay0> Assuming DONL field is not present
0:03:57.083048918 2392092 0x7ec170001060 FIXME           rtph265depay gstrtph265depay.c:1287:gst_rtp_h265_depay_process:<rtph265depay0> Assuming DONL field is not present
GST Dec Meta attached with gst decoder output buffer for Frame_Num = 7071
Attached decoder Metadata: frame type = 0, frame_num = 7071 decode_error_status = 0
0:03:57.083098988 2392092 0x7ec170001060 FIXME           rtph265depay gstrtph265depay.c:1287:gst_rtp_h265_depay_process:<rtph265depay0> Assuming DONL field is not present
0:03:57.083106442 2392092 0x7ec170001060 FIXME           rtph265depay gstrtph265depay.c:1287:gst_rtp_h265_depay_process:<rtph265depay0> Assuming DONL field is not present
0:03:57.083120083 2392092 0x7ec170001060 FIXME           rtph265depay gstrtph265depay.c:1287:gst_rtp_h265_depay_process:<rtph265depay0> Assuming DONL field is not present
GST Dec Meta attached with gst decoder output buffer for Frame_Num = 7072
Attached decoder Metadata: frame type = 1, frame_num = 7072 decode_error_status = 0
fish: Job 1, 'GST_DEBUG_NO_COLOR=1 GST_DEBUG=…' terminated by signal SIGSEGV (Address boundary error)

I will try to compile the v4l2 sources in the meantime, to get more detailed information about what is happening.

Here is the updated stack trace, after rebuilding libgstnvvideo4linux2.so with -O0 -ggdb

#0  gst_buffer_copy_into (dest=0x7fff08057490, src=0x7ffef00feac0, flags=<optimized out>, offset=0, size=780) at ../gst/gstbuffer.c:673
#1  0x00007ffff612c5ca in gst_v4l2_video_dec_loop (decoder=0x555555834990) at gstv4l2videodec.c:1307
#2  0x00007ffff7f031d7 in gst_task_func (task=0x7ffef0527ff0) at ../gst/gsttask.c:384
#3  0x00007ffff7d2ea34 in g_thread_pool_thread_proxy (data=<optimized out>) at ../glib/gthreadpool.c:350
#4  0x00007ffff7d27a91 in g_thread_proxy (data=0x7fff10001350) at ../glib/gthread.c:831
#5  0x00007ffff7694ac3 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#6  0x00007ffff7726850 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81

Which points at this part

#if USE_V4L2_TARGET_NV

    if (!gst_buffer_copy_into (frame->output_buffer, frame->input_buffer,
          (GstBufferCopyFlags)GST_BUFFER_COPY_METADATA, 0, -1)) {
      GST_DEBUG_OBJECT (decoder, "Buffer metadata copy failed \n");
    }
    if ((self->drop_frame_interval == 0) ||
        (self->decoded_picture_cnt % self->drop_frame_interval == 0))
        ret = gst_video_decoder_finish_frame (decoder, frame);
    else
        ret = gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);

    if (ret != GST_FLOW_OK)
      goto beach;

    self->decoded_picture_cnt += 1;
#else

For x86, after removing the preprocessor code, it should be here

As I guessed, I think gst_v4l2_buffer_pool_process caused the strange problem. Can you help check it?

/* No need to keep input arround */
  tmp = frame->input_buffer;
  frame->input_buffer = gst_buffer_new ();
  gst_buffer_copy_into (frame->input_buffer, tmp,
      GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS |
      GST_BUFFER_COPY_META, 0, 0);

I am sorry, I am not sure what are you asking me to do. The snippet you sent is located at the line 2190 in the same file. I have not encountered a segmentation fault in this part.

Or do you want me to try to replace the problematic copy function (line 1307) with this code?

Or do you mean that this code caused the problem as this condition was evaluated to TRUE:

  do {
    /* We cannot use the base class allotate helper since it taking the internal
     * stream lock. we know that the acquire may need to poll until more frames
     * comes in and holding this lock would prevent that.
     */
    pool = gst_video_decoder_get_buffer_pool (decoder);

    /* Pool may be NULL if we started going to READY state */
    if (pool == NULL) {
      ret = GST_FLOW_FLUSHING;
      goto beach;
    }

    ret = gst_buffer_pool_acquire_buffer (pool, &buffer, NULL);
    g_object_unref (pool);

    if (ret != GST_FLOW_OK)
      goto beach;

    GST_LOG_OBJECT (decoder, "Process output buffer");
    ret = gst_v4l2_buffer_pool_process (v4l2_pool, &buffer);

  } while (ret == GST_V4L2_FLOW_CORRUPTED_BUFFER); /// <<< THIS ONE

This confuses me, Are you using dGPU? This code should not be compiled, this is for Jetson.

So I guess it is gst_buffer_copy_into at line 2190 that causes your problem.

The problem in line 2190 may be caused by the above code.

Hello, I am using dGPU with Ubuntu 22.04 and RTX 4070.

You stated:

This confuses me, Are you using dGPU? This code should not be compiled, this is for Jetson.

However, I believe this is not entirely correct. I have looked into the Linux_for_Tegra/source/gst-v4l2/Makefile

CFLAGS += -fPIC \
	-DEXPLICITLY_ADDED=1 \
        -DGETTEXT_PACKAGE=1 \
        -DHAVE_LIBV4L2=1 \
        -DUSE_V4L2_TARGET_NV=1

There CFLAGS are used always, it does not matter whether it is a Jetson or dGPU. Therefore #if USE_V4L2_TARGET_NV will be evaluated to TRUE both on Jetson and dGPU.

Get.

If the above process can be reproduced all the time, then the problem may be caused by frame->input_buffer being an illegal pointer.

frame->input_buffer is allocated at line 2193

  frame->input_buffer = gst_buffer_new ();
#ifdef USE_V4L2_TARGET_NV
  frame = gst_v4l2_video_dec_find_nearest_frame (buffer,
          gst_video_decoder_get_frames (GST_VIDEO_DECODER (self)));
  /* So we have a timestamped  buffer and get, or not, corresponding frame.
   * Assuming decoder output frames in display order, frames preceding this
   * frame could be discarded as they seems useless due to e.g interlaced
   * stream, corrupted input data...
   * In any cases, not likely to be seen again. so drop it before they pile up
   * and use all the memory. */
  gst_v4l2_video_dec_clean_older_frames (self, buffer,
          gst_video_decoder_get_frames (GST_VIDEO_DECODER (self)));
#else

I am not sure whether the problem is caused by the call of gst_video_codec_frame_unref in gst_v4l2_video_dec_clean_older_frames/gst_v4l2_video_dec_find_nearest_frame, which causes frame->input_buffer to be released. You can check these two functions.

Just curious, is this livestream from a specific rtsp camera brand, or is it just from an RTSP server?
If it’s a rtsp camera, what model is it?

It is a streaming server, not a direct connection to camera.

I also suspected the gst_v4l2_video_dec_clean_older_frames to have something to do with it, however i have not yet found the cause of the problem.

I will look into it further once I have a bit more time on my hands.

If that’s the case, this probably doesn’t make much sense. What server are you using to reproduce the problem, and how do you publish a stream? If I have time, I can try to reproduce it.

Hello,

It is a simple mediamtx 1.5.1 server restreaming a video feed provided by ffmpeg 5.1.1.

I have been working on a Dockefile, which i could provide to you in order to replicate the issue, however I have realized that the issue does not replicate outside of the machine on which I have observed it.

Therefore, I do not have a way how to provide a replicable example and suspect a driver / hw issue on my computer.
I appreciate very much the help provided, and I am sorry there is no more info I can give.

Updating the driver seems to have helped so far, which might be useful for anyone else who might stumble on this problem as well.

Thanks for your sharing