我有这个小型 gstreamer 示例程序,它使用
appsink
和 appsrc
连接两个管道。我想从 appsink 中提取 H264 帧,对它们执行一些操作,然后使用 appsrc 读取它们。整个事情看起来接近正常,因为程序确实打开了一个窗口并显示了一个框架。但随后视频就冻结了,尽管我看到 appsink
向我发送了样本,并且我用“推送缓冲区”信号将它们推送到 appsrc
。
我的管道(代码)如下所示:
videotestsrc
到 appsink
,途中转换为 h264:videotestsrc pattern=1 is-live=true ! video/x-raw,format=I420,width=640,height=480 ! x264enc byte-stream=true ! h264parse config-interval=1 ! video/x-h264,stream-format=byte-stream ! appsink
appsrc
读取并尝试使用 autovideosink
打印:appsrc ! decodebin ! autovideosink
这就是我将缓冲区从
appsink
传递到 appsrc
的方式:
static GstFlowReturn handle_new_sample(GstAppSink *appsink, GstElement *player_appsrc) {
GstSample *sample = gst_app_sink_pull_sample(appsink);
GstFlowReturn ret = GST_FLOW_OK;
if (sample) {
// Note: this is called repeatedly, so I know I am pushing buffers to my appsrc.
char *caps = gst_caps_to_string(gst_sample_get_caps(sample));
GstBuffer *buffer = gst_sample_get_buffer(sample);
g_signal_emit_by_name(player_appsrc, "push-buffer", buffer, &ret);
gst_sample_unref(sample);
g_free(caps);
}
return ret;
}
完整代码(113行,大部分是样板代码)可以在这里获得。
我做错了什么?我应该以某种方式告诉
autovideosink
开始玩吗?
时钟计时有什么奇怪的吗?我无法发现它,但尝试一下
g_object_set(player_videosink, "sync", FALSE, NULL);
您很可能启动第二条管道,但不会立即交付样本。因此,当样本到达时,从应用程序接收器的角度来看,它们到达得很晚,并且它会丢弃所有内容。