Get "GST_MESSAGE_QOS" from nvv4l2h264enc

• DeepStream Version :5.1

Hi, everyone .
I am using “nvv4l2h264enc” to save mp4 file in pipeline
I save mp4 file every 10 seconds , After a while get “GST_MESSAGE_QOS” from “bus_call” callback ,then pipeline cann’t work

code


typedef struct _passenger_flow_info passenger_flow_info;
struct _passenger_flow_info {
  // gboolean jpg_flag;
  gboolean mp4_flag;
  gboolean tee_file;
  char filepath[FILE_NAME_SIZE];
  GstElement *pipeline;
};
static gboolean eos_fun(passenger_flow_info *p_info) {
  g_print("\nEOS\n");
  GstElement *qtmux_0 = NULL, *filesink_0 = NULL, *parse_0 = NULL,
             *qtmux_1 = NULL, *filesink_1 = NULL, *parse_1 = NULL,
             *tee_file = NULL;
  GstPad *srcpad = NULL, *sinkpad = NULL;
  tee_file = gst_bin_get_by_name(GST_BIN(p_info->pipeline), "tee_file");
  if (!p_info->tee_file) {
    parse_1 = gst_element_factory_make("h264parse", "parse_1");
    qtmux_1 = gst_element_factory_make("qtmux", "qtmux_1");
    filesink_1 = gst_element_factory_make("filesink", "filesink_1");

    time_t nowtime;
    struct tm *p;
    time(&nowtime);
    p = localtime(&nowtime);
    char filename[FILE_NAME_SIZE];
    snprintf((char *)filename, FILE_NAME_SIZE, "%s/%02d_%02d_%02d",
             p_info->filepath, p->tm_year + 1900, p->tm_mon + 1, p->tm_mday);
    if (access(filename, 0) == -1)
      mkdir(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRWXG | S_IRWXO);
    char mp4_path[FILE_NAME_SIZE];
    snprintf((char *)mp4_path, FILE_NAME_SIZE,
             "%s/video_%02d_%02d_%02d_%02d_%02d_%02d.mp4", filename,
             p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour,
             p->tm_min, p->tm_sec);
    g_print("path:%s\n", mp4_path);
    g_object_set(G_OBJECT(filesink_1), "location", mp4_path, NULL);

    gst_bin_add_many(GST_BIN(p_info->pipeline), parse_1, qtmux_1, filesink_1,
                     NULL);

    gst_element_link_many(parse_1, qtmux_1, filesink_1, NULL);

    srcpad = gst_element_get_request_pad(tee_file, "src_1");
    sinkpad = gst_element_get_static_pad(parse_1, "sink");
    if (gst_pad_link(srcpad, sinkpad) != GST_PAD_LINK_OK) {
      g_printerr("Failed to link tee to parse. Exiting.\n");
      return -1;
    }
    gst_object_unref(srcpad);
    gst_object_unref(sinkpad);

    state_return(gst_element_set_state(qtmux_1, GST_STATE_PLAYING));
    state_return(gst_element_set_state(filesink_1, GST_STATE_PLAYING));
    state_return(gst_element_set_state(parse_1, GST_STATE_PLAYING));

    gst_print("unlink\n");
    parse_0 = gst_bin_get_by_name(GST_BIN(p_info->pipeline), "parse_0");
    qtmux_0 = gst_bin_get_by_name(GST_BIN(p_info->pipeline), "qtmux_0");
    filesink_0 = gst_bin_get_by_name(GST_BIN(p_info->pipeline), "filesink_0");
    gst_element_send_event(parse_0, gst_event_new_eos());
    // sinkpad = gst_element_get_static_pad(parse_0, "sink_0");
    // gst_pad_send_event(sinkpad, gst_event_new_flush_stop(FALSE));
    // gst_object_unref(srcpad);
    state_return(gst_element_set_state(parse_0, GST_STATE_NULL));
    state_return(gst_element_set_state(qtmux_0, GST_STATE_NULL));
    state_return(gst_element_set_state(filesink_0, GST_STATE_NULL));

    gst_bin_remove(GST_BIN(p_info->pipeline), qtmux_0);
    gst_bin_remove(GST_BIN(p_info->pipeline), filesink_0);
    gst_bin_remove(GST_BIN(p_info->pipeline), parse_0);
    gst_object_unref(qtmux_0);
    gst_object_unref(filesink_0);
    gst_object_unref(parse_0);

    srcpad = gst_element_get_static_pad(tee_file, "src_0");
    gst_element_release_request_pad(tee_file, srcpad);
    gst_object_unref(srcpad);
    p_info->tee_file = true;
  } else {
    parse_0 = gst_element_factory_make("h264parse", "parse_0");
    qtmux_0 = gst_element_factory_make("qtmux", "qtmux_0");
    filesink_0 = gst_element_factory_make("filesink", "filesink_0");

    time_t nowtime;
    struct tm *p;
    time(&nowtime);
    p = localtime(&nowtime);
    char filename[FILE_NAME_SIZE];

    snprintf((char *)filename, FILE_NAME_SIZE, "%s/%02d_%02d_%02d",
             p_info->filepath, p->tm_year + 1900, p->tm_mon + 1, p->tm_mday);
    if (access(filename, 0) == -1)
      mkdir(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRWXG | S_IRWXO);
    char mp4_path[FILE_NAME_SIZE];
    snprintf((char *)mp4_path, FILE_NAME_SIZE,
             "%s/video_%02d_%02d_%02d_%02d_%02d_%02d.mp4", filename,
             p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour,
             p->tm_min, p->tm_sec);
    g_print("path:%s\n", mp4_path);
    g_object_set(G_OBJECT(filesink_0), "location", mp4_path, NULL);

    gst_bin_add_many(GST_BIN(p_info->pipeline), parse_0, qtmux_0, filesink_0,
                     NULL);

    gst_element_link_many(parse_0, qtmux_0, filesink_0, NULL);

    srcpad = gst_element_get_request_pad(tee_file, "src_0");
    sinkpad = gst_element_get_static_pad(parse_0, "sink");
    if (gst_pad_link(srcpad, sinkpad) != GST_PAD_LINK_OK) {
      g_printerr("Failed to link tee to parse. Exiting.\n");
      return -1;
    }
    gst_object_unref(srcpad);
    gst_object_unref(sinkpad);

    state_return(gst_element_set_state(qtmux_0, GST_STATE_PLAYING));
    state_return(gst_element_set_state(filesink_0, GST_STATE_PLAYING));
    state_return(gst_element_set_state(parse_0, GST_STATE_PLAYING));

    gst_print("unlink\n");
    parse_1 = gst_bin_get_by_name(GST_BIN(p_info->pipeline), "parse_1");
    qtmux_1 = gst_bin_get_by_name(GST_BIN(p_info->pipeline), "qtmux_1");
    filesink_1 = gst_bin_get_by_name(GST_BIN(p_info->pipeline), "filesink_1");
    gst_element_send_event(parse_1, gst_event_new_eos());
    state_return(gst_element_set_state(qtmux_1, GST_STATE_NULL));
    state_return(gst_element_set_state(filesink_1, GST_STATE_NULL));
    state_return(gst_element_set_state(parse_1, GST_STATE_NULL));

    gst_bin_remove(GST_BIN(p_info->pipeline), qtmux_1);
    gst_bin_remove(GST_BIN(p_info->pipeline), filesink_1);
    gst_bin_remove(GST_BIN(p_info->pipeline), parse_1);
    gst_object_unref(qtmux_1);
    gst_object_unref(filesink_1);
    gst_object_unref(parse_1);

    srcpad = gst_element_get_static_pad(tee_file, "src_1");
    gst_element_release_request_pad(tee_file, srcpad);
    gst_object_unref(srcpad);
    p_info->tee_file = false;
  }
  return true;
}
int main(int argc, char *argv[]) {
  GMainLoop *loop = NULL;
  GstElement *streammux = NULL, *tee = NULL, *tee_file = NULL,
             *nvvidconv = NULL, *nvosd = NULL, *nvosd_post = NULL,
             *filter = NULL, *encoder = NULL, *rtppay = NULL, *sink = NULL,
             *nvvidconv_file = NULL, *h264enc_file = NULL, *parse = NULL,
             *qtmux = NULL, *filesink = NULL, *queue1 = NULL, *queue2 = NULL,
             *queue3 = NULL, *queue4 = NULL, *queue5 = NULL, *queue6 = NULL,
             *pgie = NULL, *tracker = NULL, *nvdsanalytics = NULL;
  GstPad *sinkpad, *srcpad, *nvosd_src_pad;
  GstBus *bus = NULL;
  passenger_flow_info *p_info;
  p_info = g_slice_alloc0(sizeof(passenger_flow_info));
  // check device
  int current_device = -1;
  cudaGetDevice(&current_device);
  struct cudaDeviceProp prop;
  cudaGetDeviceProperties(&prop, current_device);
  // gst_init
  gst_init(&argc, &argv);
  loop = g_main_loop_new(NULL, FALSE);
  p_info->pipeline = gst_pipeline_new("NN_passenger_flow");
  // make some element
  streammux = gst_element_factory_make("nvstreammux", "stream");
 
  GstElement *source_bin = create_source_bin(
      0,rtspurl);
  pgie = gst_element_factory_make("nvinfer", "pgie-nvinfer");
  tracker = gst_element_factory_make("nvtracker", "tracker");
  nvdsanalytics = gst_element_factory_make("nvdsanalytics", "analytics");
  nvvidconv = gst_element_factory_make("nvvideoconvert", "nvvideo-converter");
  nvosd = gst_element_factory_make("nvdsosd", "nv-onscreendisplay");
  tee = gst_element_factory_make("tee", "tee");

  // to rtsp
  nvosd_post = gst_element_factory_make("nvvideoconvert", "convertor_postosd");
  encoder = gst_element_factory_make("nvv4l2h264enc", "encoder");
  filter = gst_element_factory_make("capsfilter", "filter");
  rtppay = gst_element_factory_make("rtph264pay", "rtppay");
  sink = gst_element_factory_make("udpsink", "udpsink");

  // to mp4 file
  nvvidconv_file = gst_element_factory_make("nvvideoconvert", "convertor_file");
  h264enc_file = gst_element_factory_make("nvv4l2h264enc", "h264enc");
  tee_file = gst_element_factory_make("tee", "tee_file");
  parse = gst_element_factory_make("h264parse", "parse_0");
  qtmux = gst_element_factory_make("qtmux", "qtmux_0");
  filesink = gst_element_factory_make("filesink", "filesink_0");

  // queue
  queue1 = gst_element_factory_make("queue", "queue1");
  queue2 = gst_element_factory_make("queue", "queue2");
  queue3 = gst_element_factory_make("queue", "queue3");
  queue4 = gst_element_factory_make("queue", "queue4");
  queue5 = gst_element_factory_make("queue", "queue5");
  queue6 = gst_element_factory_make("queue", "queue6");

  g_object_set(G_OBJECT(streammux), "width", 1920, "height", 1080, "batch-size",
               1, "live-source", 1, "batched-push-timeout", 40000, NULL);
  g_object_set(G_OBJECT(pgie), "config-file-path",
               "nvdsanalytics_pgie_config.txt", NULL);
  if (!set_tracker_properties(tracker)) {
    g_printerr("Failed to set tracker properties. Exiting.\n");
    return -1;
  }
  g_object_set(G_OBJECT(nvdsanalytics), "config-file",
               "config_nvdsanalytics.txt", NULL);
  g_object_set(G_OBJECT(encoder), "bitrate", 4000000, NULL);
  g_object_set(G_OBJECT(sink), "host", "224.224.255.255", "port", 18000,
               "async", false, "sync", 1, NULL);
  GstCaps *caps = NULL;
  caps = gst_caps_from_string("video/x-raw(memory:NVMM),format=I420");
  g_object_set(G_OBJECT(filter), "caps", caps, NULL);
  gst_caps_unref(caps);
  g_object_set(G_OBJECT(nvvidconv_file), "qos", true, NULL);
  g_object_set(G_OBJECT(h264enc_file), "qos", true, NULL);

  snprintf((char *)p_info->filepath, FILE_NAME_SIZE, "tet");
  time_t nowtime;
  struct tm *p;
  char filename[FILE_NAME_SIZE];
  time(&nowtime);
  p = localtime(&nowtime);
  snprintf((char *)filename, FILE_NAME_SIZE, "%s/%02d_%02d_%02d",
           p_info->filepath, p->tm_year + 1900, p->tm_mon + 1, p->tm_mday);
  if (access(filename, 0) == -1)
    mkdir(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRWXG | S_IRWXO);
  char mp4_path[FILE_NAME_SIZE];
  snprintf((char *)mp4_path, FILE_NAME_SIZE,
           "%s/video_%02d_%02d_%02d_%02d_%02d_%02d.mp4", filename,
           p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min,
           p->tm_sec);

  g_object_set(GST_OBJECT(filesink), "location", mp4_path, NULL);

  // add elements to pipeline and link
  gst_bin_add_many(GST_BIN(p_info->pipeline), source_bin, streammux, pgie,
                   queue1, tracker, nvdsanalytics, nvvidconv, queue2, nvosd,
                   tee, queue3, nvosd_post, filter, encoder, rtppay, sink,
                   queue4, nvvidconv_file, queue6, h264enc_file, parse,
                   tee_file, queue5, qtmux, filesink, NULL);

  gst_element_link_many(streammux, pgie, queue1, tracker, nvdsanalytics,
                        nvvidconv, queue2, nvosd, tee, NULL);
  gst_element_link_many(queue3, nvosd_post, filter, encoder, rtppay, sink,
                        NULL);
  gst_element_link_many(queue4, nvvidconv_file, queue6, h264enc_file, tee_file,
                        NULL);
  gst_element_link_many(parse, qtmux, filesink, NULL);

  // link source to streammux
  sinkpad = gst_element_get_request_pad(streammux, "sink_0");
  srcpad = gst_element_get_static_pad(source_bin, "src");
  if (!srcpad) {
    g_printerr("Failed to get src pad of source bin. Exiting.\n");
    return -1;
  }
  if (gst_pad_link(srcpad, sinkpad) != GST_PAD_LINK_OK) {
    g_printerr("Failed to link source bin to stream muxer. Exiting.\n");
    return -1;
  }
  gst_object_unref(srcpad);
  gst_object_unref(sinkpad);

  // link src_0 of tee to RTSP
  srcpad = gst_element_get_request_pad(tee, "src_0");
  sinkpad = gst_element_get_static_pad(queue3, "sink");
  if (gst_pad_link(srcpad, sinkpad) != GST_PAD_LINK_OK) {
    g_printerr("Failed to link tee to queue3. Exiting.\n");
    return -1;
  }
  gst_object_unref(srcpad);
  gst_object_unref(sinkpad);

  // link src_1 of tee to mp4
  srcpad = gst_element_get_request_pad(tee, "src_1");
  sinkpad = gst_element_get_static_pad(queue4, "sink");
  if (gst_pad_link(srcpad, sinkpad) != GST_PAD_LINK_OK) {
    g_printerr("Failed to link tee to queue3. Exiting.\n");
    return -1;
  }
  gst_object_unref(srcpad);
  gst_object_unref(sinkpad);

  // link src_1 of tee to mp4_0
  srcpad = gst_element_get_request_pad(tee_file, "src_0");
  sinkpad = gst_element_get_static_pad(parse, "sink");
  if (gst_pad_link(srcpad, sinkpad) != GST_PAD_LINK_OK) {
    g_printerr("Failed to link tee to queue5. Exiting.\n");
    return -1;
  }
  gst_object_unref(srcpad);
  gst_object_unref(sinkpad);


  bus = gst_pipeline_get_bus(GST_PIPELINE(p_info->pipeline));
  gst_bus_add_watch(bus, bus_call, loop);

  // rtsp server
  GstRTSPServer *server;
  GstRTSPMountPoints *mounts;
  GstRTSPMediaFactory *factory;
  server = gst_rtsp_server_new();

  mounts = gst_rtsp_server_get_mount_points(server);

  factory = gst_rtsp_media_factory_new();

  g_object_set(server, "service", "8555", NULL);
  gst_rtsp_media_factory_set_launch(
      factory, "( udpsrc name=pay0 port=18000 buffer-size=524288 "
               "caps=\"application/x-rtp, media=video, clock-rate=90000, "
               "encoding-name=(string)H264, payload=96 \" )");
  gst_rtsp_media_factory_set_shared(factory, TRUE);
  gst_rtsp_mount_points_add_factory(mounts, "/ds-test", factory);
  g_object_unref(mounts);
  gst_rtsp_server_attach(server, NULL);

  gst_element_set_state(p_info->pipeline, GST_STATE_PLAYING);

  g_timeout_add_seconds(10, eos_fun, (passenger_flow_info *)p_info);
  g_print("Running...\n");

  g_main_loop_run(loop);

  /* Out of the main loop, clean up nicely */
  g_print("Returned, stopping playback\n");
  gst_element_set_state(p_info->pipeline, GST_STATE_NULL);
  g_print("Deleting pipeline\n");

  gst_object_unref(GST_OBJECT(p_info->pipeline));
  g_main_loop_unref(loop);
  return 0;
}

pipeline

log

Qos
type:16777216
src:h264enc

Do you have any ideas? Looking forward to your reply

When you received QOS message from encoder, that means there is frame drop happen in the encoder. gst-libs/gst/video/gstvideoencoder.c · 1.14 · GStreamer / gst-plugins-base · GitLab. This will not stop the pipeline unless you handle the message incorrectly in “bus_call”. Please debug for the real reason.

Hi,thanks for your reply,I didn’t set anything in the "bus_call"callback function

static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data) {
  GMainLoop *loop = (GMainLoop *)data;
  g_print("type:%d\n", GST_MESSAGE_TYPE(msg));
  g_print("src:%s\n", GST_OBJECT_NAME(msg->src));
  switch (GST_MESSAGE_TYPE(msg)) {
  case GST_MESSAGE_EOS:
    g_print("End of stream\n");
    g_main_loop_quit(loop);
    break;
  case GST_MESSAGE_WARNING: {
    gchar *debug;
    GError *error;
    gst_message_parse_warning(msg, &error, &debug);
    g_printerr("WARNING from element %s: %s\n", GST_OBJECT_NAME(msg->src),
               error->message);
    g_free(debug);
    g_printerr("Warning: %s\n", error->message);
    g_error_free(error);
    break;
  }
  case GST_MESSAGE_ERROR: {
    gchar *debug;
    GError *error;
    gst_message_parse_error(msg, &error, &debug);
    g_printerr("ERROR from element %s: %s\n", GST_OBJECT_NAME(msg->src),
               error->message);
    if (debug)
      g_printerr("Error details: %s\n", debug);
    g_free(debug);
    g_error_free(error);
    g_main_loop_quit(loop);
    break;
  }

  // #ifndef PLATFORM_TEGRA
  //   case GST_MESSAGE_ELEMENT: {
  //     if (gst_nvmessage_is_stream_eos(msg)) {
  //       guint stream_id;
  //       if (gst_nvmessage_parse_stream_eos(msg, &stream_id)) {
  //         g_print("Got EOS from stream %d\n", stream_id);
  //       }
  //     }
  //     break;
  //   }
  // #endif
  default:
    break;
  }
  return TRUE;
}

there is my code, please change Rtspurl in 454 line.

code.c (24.1 KB)

run the code , After a while get “type:16777216 src:h264enc” from bus_call ,then rtsp and filesink are not output any,pipeline can’t work

No clue show the failure is caused by nvv4l2h264enc. Please debug by yourself.

OK, thansk for you reply

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.