代码之家  ›  专栏  ›  技术社区  ›  Crearo Rotar

用于大型缓冲器的GSTAPSRC

  •  2
  • Crearo Rotar  · 技术社区  · 7 年前

    我的管道是:

    appsrc ! identity ! rtpvrawpay ! udpsink
    

    appsrc 是640*480原始RGBA32未压缩字节数组,每秒30帧-这是 非常慢 identity 应用程序 使用

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

    在640*480原始RGBA 32位未压缩时 身份 一切都保持不变,320*240的原始帧大约每秒12帧,而160*120的原始帧则可以达到整整30帧。这是一个已知的问题吗 GstAppSrc ?


    没有帧被丢弃 应用程序 . 他们都在排队;我查过了 GST_BUFFER_PTS 要查看是否有任何帧正在被丢弃,请将其设置为 应用程序 身份 .

    设置 AppSrc

    data->src = gst_bin_get_by_name(GST_BIN(data->pipeline), "camsrc");
    
    g_object_set(G_OBJECT(data->src), "caps",
                 gst_caps_new_simple("video/x-raw",
                                     "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;
    
    g_object_set(G_OBJECT(data->src),
                 "stream-type", GST_APP_STREAM_TYPE_STREAM,
                 "format", GST_FORMAT_TIME,
                 "block", FALSE,
                 "max-bytes", queue_size,
                 "size", frame_size,
                 "is-live", TRUE,
                 NULL);
    

    使用以下函数将帧从Java传送到C:

    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, 0);
    
        // 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 CLOCK_REALTIME 
        gstbuffer = gst_buffer_new_allocate(NULL, size, NULL);
        gst_buffer_map(gstbuffer, &map, GST_MAP_WRITE);
        memcpy((char *) map.data, pbuffer, (int) size);
    
        gst_buffer_unmap(gstbuffer, &map);
    
        GST_BUFFER_PTS(gstbuffer) = timestamp;
        LOGD("add_stream timestamp %"G_GUINT64_FORMAT, GST_BUFFER_PTS (gstbuffer));
        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);
        gst_buffer_unref(gstbuffer);
    
        return;
    }
    

    度量fps的标识回调:

    static void cb_identity_handoff (GstElement *identity, GstBuffer *buffer, CustomData *data) {
        frame_counter++;
        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;
        }
    }
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   micha137    7 年前

    所有元素都在一个线程中运行。放一个 queue

    appsrc ! queue ! identity ! rtpvrawpay ! udpsink