Allocate buffer duration with frame-rate value using GST_BUFFER_DURATION

Shaf shaf.nttf at gmail.com
Thu Apr 25 02:43:23 UTC 2019


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/


More information about the gstreamer-devel mailing list