#include #include #include #include #ifndef FPS #define FPS 30 #endif using namespace std; namespace { constexpr size_t g_fps { FPS }; constexpr GstClockTime g_frame_reference_duration { static_cast(round(static_cast(GST_SECOND) / g_fps)) }; GstPadProbeReturn on_source_buffer(GstPad* pad, GstPadProbeInfo* info, gpointer user_data) { GstBuffer* const buf = GST_BUFFER(info->data); const GstClockTime current_time { buf->pts }; static GstClockTime prev_time { current_time }; static size_t counter { }; static GstClockTime prev_avg_print_time { current_time }; static GstClockTime avg_buffer { current_time }; const GstClockTime duration { current_time - prev_time }; prev_time = current_time; if (counter + 1) avg_buffer = (avg_buffer * counter + duration) / (counter + 1); ++counter; if (current_time - prev_avg_print_time > 10 * GST_SECOND) { cout << "average duration: " << avg_buffer << " (" << showpos << static_cast(avg_buffer) - static_cast(g_frame_reference_duration) << ')' << " ns" << endl; prev_avg_print_time = current_time; } return GST_PAD_PROBE_OK; } } int main (int argc, char *argv[]) { /* Initialize GStreamer */ gst_init(&argc, &argv); GstElement* const pipeline { gst_pipeline_new("nvarguscamerasrc-framerate-issue-test") }; GstElement* const source { gst_element_factory_make("nvarguscamerasrc", "source") }; GstElement* const capsfilter { gst_element_factory_make("capsfilter", "capsfilter") }; GstElement* const sink { gst_element_factory_make("fakesink", "sink") }; gst_bin_add_many(GST_BIN(pipeline), source, capsfilter, sink, nullptr); { GstCaps* const input_caps { gst_caps_new_simple("video/x-raw", "width", G_TYPE_INT, 1280, "height", G_TYPE_INT, 720, "framerate", GST_TYPE_FRACTION, g_fps, 1, nullptr) }; GstCapsFeatures* const memory_features { gst_caps_features_new("memory:NVMM", nullptr) }; gst_caps_set_features(input_caps, 0, memory_features); g_object_set(capsfilter, "caps", input_caps, nullptr); } gst_element_link_many(source, capsfilter, sink, nullptr); GstPad* const src_pad { gst_element_get_static_pad(source, "src") }; gst_pad_add_probe(src_pad, GST_PAD_PROBE_TYPE_BUFFER, on_source_buffer, nullptr, nullptr); gst_object_unref(src_pad); gst_element_set_state(pipeline, GST_STATE_PLAYING); GMainLoop* const main_loop { g_main_loop_new(nullptr, false) }; g_main_loop_run(main_loop); g_main_loop_unref(main_loop); return 0; }