I am trying to stream multiple (.mp4) videos using RTSP pipeline. By using
appsrc push-buffer, I am able to push the buffer retrieved from appsink pipeline [Thanks to nabble forum from where I took the bits and pieces to work it out]. Everything works fine, but when I have video files with different frame-rate, I noticed that there is a lag/stuck in video display. Then I noticed that the behavior is due to the buffer duration. In the needData callback of appsrc, the buffer is pushed as shown below. GST_BUFFER_PTS(buffer) = ctx->timestamp; GST_BUFFER_DURATION(buffer) = gst_util_uint64_scale_int(1001, GST_SECOND, 30000); ctx->timestamp += GST_BUFFER_DURATION(buffer); g_signal_emit_by_name(appsrc, "push-buffer", buffer, &ret); I would like to change the scale based on frame-rate of the caps received from the sample. Something like gst_util_uint64_scale_int(<rate>, GST_SECOND, <frames>). But the frame-rate that is received from the caps structure is a char* 30000/1001. How can I pass the value of framerate to create buffer Duration ? Expected : gst_util_uint64_scale_int(1001, GST_SECOND, 30000). Note : Different video has different frame-rate, so I would like to do it dynamically. Or, is there any other way to achieve this ? Refer the attachment for the rtsp server source. // needData call-back function void needData(GstElement *appsrc, guint unused, Context *ctx) { GstFlowReturn ret; GstBuffer *buffer; GstStructure *capsstruct; GstSample *sample = gst_app_sink_pull_sample(GST_APP_SINK(ctx->glblapp->sink)); gint width, height; while (sample == NULL) { g_warning(" Waiting to fetch sample "); sample = gst_app_sink_pull_sample(GST_APP_SINK(ctx->glblapp->sink)); } GstCaps *capsfromsink = fetch_caps(ctx->glblapp->sink, "sink"); buffer = gst_sample_get_buffer(sample); //g_object_set(G_OBJECT(appsrc), "caps", gst_caps_from_string(videocaps), NULL); if (capsfromsink != NULL) { g_object_set(G_OBJECT(appsrc), "caps", capsfromsink, NULL); } capsstruct = gst_caps_get_structure(capsfromsink, 0); if (gst_structure_has_field(capsstruct, "framerate")) { * /// here I get the framerate as 3000/1001/* gchar *framerate = gst_value_serialize(gst_structure_get_value(capsstruct, "framerate")); g_free(framerate); } GST_BUFFER_PTS(buffer) = ctx->timestamp; GST_BUFFER_DURATION(buffer) = gst_util_uint64_scale_int(1001, GST_SECOND, 30000); ctx->timestamp += GST_BUFFER_DURATION(buffer); g_signal_emit_by_name(appsrc, "push-buffer", buffer, &ret); gst_sample_unref(sample); } -- Sent from: http://gstreamer-devel.966125.n4.nabble.com/ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
I found the below solution working. GstStructure *capsstruct; gint rate = 1, frames = 30; capsstruct = gst_caps_get_structure(caps, 0); if (gst_structure_has_field(capsstruct, FRAMERATE)) { const GValue *framerate_val = gst_structure_get_value(capsstruct, FRAMERATE); if (G_VALUE_TYPE(framerate_val) == GST_TYPE_FRACTION) { frames = gst_value_get_fraction_numerator(framerate_val); rate = gst_value_get_fraction_denominator(framerate_val); } } GST_BUFFER_PTS(buffer) = ctx->timestamp; GST_BUFFER_DURATION(buffer) = gst_util_uint64_scale_int(rate, GST_SECOND, frames); -- Sent from: http://gstreamer-devel.966125.n4.nabble.com/ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Free forum by Nabble | Edit this page |