GstAppSrc for large buffers

k4ustav kaustav.ghosh28 at
Tue Sep 18 07:33:42 UTC 2018

My pipeline is:

    appsrc ! identity ! rtpvrawpay ! udpsink

The buffers being passed to `appsrc` are 640*480 raw RGBA32 uncompressed
byte arrays at 30fps - which is **terribly slow**. I'm using the `identity`
element to measure how frequently it is receiving frames from `appsrc` using 

    g_signal_connect(data->identity, "handoff", cb_identity_handoff, data);

At 640*480 raw RGBA 32 bit uncompressed, the `identity` element receives
frames at ~2fps.
Everything kept same, 320*240 raw frames give about ~12fps, and at 160*120
it gives a full 30fps. Is this a known issue with `GstAppSrc`?


**Extra info:**

No frames are being dropped by `appsrc`. They're all queued; I checked using
`GST_BUFFER_PTS` to see if any of the frames are being dropped, by setting
them while pushing them to `appsrc`, and reading them at `identity`.


Setting up `AppSrc`:

    data->src = gst_bin_get_by_name(GST_BIN(data->pipeline), "camsrc");

    g_object_set(G_OBJECT(data->src), "caps",
                                     "format", G_TYPE_STRING, "RGBA",
                                     "width", G_TYPE_INT, 640,
                                     "height", G_TYPE_INT, 480,
                                     "framerate", GST_TYPE_FRACTION, 30, 1,
                                      NULL), NULL);

    gint64 frame_size = 640*480*4;
    gint64 queue_size = 100*640*480*4;

                 "stream-type", GST_APP_STREAM_TYPE_STREAM,
                 "format", GST_FORMAT_TIME,
                 "block", FALSE,
                 "max-bytes", queue_size,
                 "size", frame_size,
                 "is-live", TRUE,

Frames are fed from Java to C using the following function:

    static void gst_add_stream(JNIEnv *env, jobject thiz, jbyteArray buffer,
jint size, jlong ptime,
                               jlong custom_data) {
        CustomData *data = (CustomData *) (jint)
custom_data;//GET_CUSTOM_DATA (env, thiz, custom_data);
        if (!data || size == 0) return;

        GstBuffer *gstbuffer;
        GstMapInfo map;
        GstFlowReturn ret;

        GstClockTime timestamp = ptime;

        jbyte *pbuffer = (jbyte *) (*env)->GetByteArrayElements(env, buffer,

        // though I'm doing a memcopy here, and allocating, I've measured
the time and it doesn't seem to be taking more than 2ms. Using
        gstbuffer = gst_buffer_new_allocate(NULL, size, NULL);
        gst_buffer_map(gstbuffer, &map, GST_MAP_WRITE);
        memcpy((char *), pbuffer, (int) size);

        gst_buffer_unmap(gstbuffer, &map);

        GST_BUFFER_PTS(gstbuffer) = timestamp;
        LOGD("add_stream timestamp %"G_GUINT64_FORMAT, GST_BUFFER_PTS
        GST_BUFFER_DURATION(gstbuffer) = gst_util_uint64_scale_int(1,
GST_SECOND, data->framerate);
        g_signal_emit_by_name(data->src, "push-buffer", gstbuffer, &ret);

        if (ret != GST_FLOW_OK) {
            g_debug("push buffer returned %d for %d bytes \n", ret, size);

        (*env)->ReleaseByteArrayElements(env, buffer, pbuffer, 0);


The identity callback that measures fps:

    static void cb_identity_handoff (GstElement *identity, GstBuffer
*buffer, CustomData *data) {
        double diff = (now_ms() - last_time);
        if (diff > 1000){
            LOGD("add frames: %.2f", frame_counter / diff * 1000.0f);
            last_time = now_ms();
            frame_counter = 0;

Sent from:

More information about the gstreamer-devel mailing list