GStreamer 管道播放,但没有 pad-added 回调(仅发生在 Android、Windows 和 Linux 上有效)
GStreamer pipeline playing, but no pad-added callback (only happens on Android, on Windows and Linux it works)
我在 Android 上使用 GStreamer(版本 1.14.1)并且已经有一个适用于 Windows 和 Linux 的实现(在 C++ 代码中)。
我按照 GStreamer 网站上的 Android 教程构建了我自己的 gstreamer-android.so
库,以便在 Android Studio 中使用。在我的 C++ 代码中,我添加了
GST_PLUGIN_STATIC_DECLARE
和 GST_PLUGIN_STATIC_REGISTER
宏来注册静态插件。
在运行时,可以成功创建所有 GstElements。 (我正在使用 gst_element_factory_make()
调用来做到这一点。)
我这样构建管道:
GstCaps* video_caps = gst_caps_new_full(
gst_structure_new("video/x-raw", "format", G_TYPE_STRING, "RGBA", NULL),
gst_structure_new("video/x-h264", "format", G_TYPE_STRING, "RGBA", NULL),
NULL);
g_object_set(m_app_sink, "emit-signals", TRUE, "caps", video_caps, NULL);
g_signal_connect(m_app_sink, "new-sample", G_CALLBACK(cb_new_sample), this);
gst_bin_add_many(GST_BIN(m_pipeline), source, m_decoder, m_video_flip, m_queue, m_video_convert, m_app_sink, NULL);
if (!gst_element_link_many(source, m_decoder, NULL)) {
gst_object_unref(m_pipeline);
return false;
}
if (!gst_element_link_many(m_video_flip, m_queue, m_video_convert, m_app_sink, NULL)) {
gst_object_unref(m_pipeline);
return false;
}
g_signal_connect(m_decoder, "pad-added", G_CALLBACK(cb_pad_added), this);
稍后在代码中以 gst_element_set_state(m_pipeline, GST_STATE_PLAYING);
开头
我正在使用不同的元素来执行此操作,例如 source
:filesrc
、udpsrc
和 videotestsrc
。
当我将管道切换到播放状态时,我希望从 decodebin
获得 pad-added
回调被触发,然后我在那里进行打击垫的链接。所有这一切都已经在 Windows 和 Linux 上为所有 3 个来源工作。
在 Android 上,回调仅针对 videotestsrc
触发,但如果我使用其他来源之一则不会。
但是我错过了什么?为什么它适用于 videotestsrc 但不适用于文件和 udp 流? (Android 应用程序中的权限设置已正确设置,静态插件已注册。)
有人知道 Android 上的示例实现,其中管道是手动构建并带有回调的吗? (到目前为止,我只能找到 playbin
的示例,我无法使用它,因为我需要从视频流中抓取帧。)
我真是没脑子,怎么没收到这个回调。非常感谢任何帮助和建议。谢谢!
更新:
在创建我自己的调试函数后(在 this post 之后),我发现 H.264 的编码器插件存在问题。
2019-07-30 09:56:29.034 27551-27611/at.myapp.player E/GStreamer.cpp:: gstdecodebin2.c,gst_decode_bin_expose: error: no suitable plugins found:
Missing decoder: H.264 (Constrained Baseline Profile) (video/x-h264, stream-format=(string)avc, alignment=(string)au, level=(string)4, profile=(string)constrained-baseline, codec_data=(buffer)0142c028ffe1001c6742c028db01e0089f97016a020202800000030080015f90078c197001000568ca8132c8, width=(int)1920, height=(int)1080, framerate=(fraction)25/1, pixel-aspect-ratio=(fraction)1/1)
但是我还不知道怎么解决。我虽然通过添加 GST_PLUGIN_STATIC_REGISTER(openh264);
这应该在那里,不是吗?
好的,我知道了!
我添加了 GST_PLUGIN_STATIC_REGISTER(videoparsersbad)
,现在一切正常! :)
我在 Android 上使用 GStreamer(版本 1.14.1)并且已经有一个适用于 Windows 和 Linux 的实现(在 C++ 代码中)。
我按照 GStreamer 网站上的 Android 教程构建了我自己的 gstreamer-android.so
库,以便在 Android Studio 中使用。在我的 C++ 代码中,我添加了
GST_PLUGIN_STATIC_DECLARE
和 GST_PLUGIN_STATIC_REGISTER
宏来注册静态插件。
在运行时,可以成功创建所有 GstElements。 (我正在使用 gst_element_factory_make()
调用来做到这一点。)
我这样构建管道:
GstCaps* video_caps = gst_caps_new_full(
gst_structure_new("video/x-raw", "format", G_TYPE_STRING, "RGBA", NULL),
gst_structure_new("video/x-h264", "format", G_TYPE_STRING, "RGBA", NULL),
NULL);
g_object_set(m_app_sink, "emit-signals", TRUE, "caps", video_caps, NULL);
g_signal_connect(m_app_sink, "new-sample", G_CALLBACK(cb_new_sample), this);
gst_bin_add_many(GST_BIN(m_pipeline), source, m_decoder, m_video_flip, m_queue, m_video_convert, m_app_sink, NULL);
if (!gst_element_link_many(source, m_decoder, NULL)) {
gst_object_unref(m_pipeline);
return false;
}
if (!gst_element_link_many(m_video_flip, m_queue, m_video_convert, m_app_sink, NULL)) {
gst_object_unref(m_pipeline);
return false;
}
g_signal_connect(m_decoder, "pad-added", G_CALLBACK(cb_pad_added), this);
稍后在代码中以 gst_element_set_state(m_pipeline, GST_STATE_PLAYING);
我正在使用不同的元素来执行此操作,例如 source
:filesrc
、udpsrc
和 videotestsrc
。
当我将管道切换到播放状态时,我希望从 decodebin
获得 pad-added
回调被触发,然后我在那里进行打击垫的链接。所有这一切都已经在 Windows 和 Linux 上为所有 3 个来源工作。
在 Android 上,回调仅针对 videotestsrc
触发,但如果我使用其他来源之一则不会。
但是我错过了什么?为什么它适用于 videotestsrc 但不适用于文件和 udp 流? (Android 应用程序中的权限设置已正确设置,静态插件已注册。)
有人知道 Android 上的示例实现,其中管道是手动构建并带有回调的吗? (到目前为止,我只能找到 playbin
的示例,我无法使用它,因为我需要从视频流中抓取帧。)
我真是没脑子,怎么没收到这个回调。非常感谢任何帮助和建议。谢谢!
更新:
在创建我自己的调试函数后(在 this post 之后),我发现 H.264 的编码器插件存在问题。
2019-07-30 09:56:29.034 27551-27611/at.myapp.player E/GStreamer.cpp:: gstdecodebin2.c,gst_decode_bin_expose: error: no suitable plugins found:
Missing decoder: H.264 (Constrained Baseline Profile) (video/x-h264, stream-format=(string)avc, alignment=(string)au, level=(string)4, profile=(string)constrained-baseline, codec_data=(buffer)0142c028ffe1001c6742c028db01e0089f97016a020202800000030080015f90078c197001000568ca8132c8, width=(int)1920, height=(int)1080, framerate=(fraction)25/1, pixel-aspect-ratio=(fraction)1/1)
但是我还不知道怎么解决。我虽然通过添加 GST_PLUGIN_STATIC_REGISTER(openh264);
这应该在那里,不是吗?
好的,我知道了!
我添加了 GST_PLUGIN_STATIC_REGISTER(videoparsersbad)
,现在一切正常! :)