我的管道是:
appsrc ! identity ! rtpvrawpay ! udpsink
传递给appsrc
的缓冲区是640 * 480原始RGBA32未压缩字节数组,速率为30fps-非常慢。我正在使用identity
元素来测量
appsrc
接收帧的频率。
g_signal_connect(data->identity, "handoff", cb_identity_handoff, data);
在未经压缩的640 * 480原始RGBA 32位下,identity
元素以〜2fps的速度接收帧。
一切保持不变,320 * 240原始帧可提供约12fps的帧率,而160 * 120的原始帧可提供完整的30fps的帧率。这是GstAppSrc
的已知问题吗?
其他信息:
appsrc
没有丢帧。他们都排队了。我使用GST_BUFFER_PTS
检查了一下是否丢掉了所有帧,方法是将它们推到appsrc
并在identity
处读取它们来进行设置。
代码:
设置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;
}
}
答案 0 :(得分:0)
所有元素都在一个线程中运行。将 queue 元素放入您的管道中,所有以下元素将从该管道在另一个线程中运行:
appsrc ! queue ! identity ! rtpvrawpay ! udpsink