我的应用程序中有一个很奇怪的问题。计划是使用gstreamer播放一个视频流并将其显示在SurfaceView上。管道使用glimagesink
来显示视频。Android上的gstreamer:重新启动管道时发生异常?
当我的活动终止时,它调用release_pipeline
(将管道状态设置为GST_STATE_NULL,取消它,将我的引用设置为NULL)。在这个错误unrefing结果,我不知道是什么导致它:
validate_display:211 error 3001 (EGL_NOT_INITIALIZED)
后跟一个段错误。该应用程序实际上在Android的编排器中崩溃,但我不知道该从哪里去。
的SurfaceView生活片段内并具有在surfaceDestroyed
调用surface_release
,并呼吁在surfaceChanged
surface_update
一个回调。该回调加入onCreateView
。 我的对象保存在名为jnictx的extern
结构中。这些函数被定义为:
void surface_release()
{
if (jnictx->gst.pipeline != NULL)
{
GstElement* vsink = gst_bin_get_by_name(jnictx->gst.pipeline, "vr_sink");
gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(vsink), (guintptr) NULL);
gst_element_set_state(GST_ELEMENT(jnictx->gst.pipeline), GST_STATE_READY);
gst_object_unref(vsink);
}
if (jnictx->gst.surface_win != NULL)
{
ANativeWindow_release(jnictx->gst.surface_win);
jnictx->gst.surface_win = NULL;
}
}
void surface_update(JNIEnv* env, jobject surface)
{
ANativeWindow *new_window = ANativeWindow_fromSurface(env, surface);
if (jnictx->gst.surface_win != NULL)
{
// Release the old reference
ANativeWindow_release(jnictx->gst.surface_win);
// The window did not change, just update the surface
if (jnictx->gst.surface_win == new_window)
{
if (jnictx->gst.pipeline != NULL)
{
GstElement* vsink = gst_bin_get_by_name(jnictx->gst.pipeline, "vr_sink");
// Supposedly we have to call this twice so the surface updates with the new values
gst_video_overlay_expose(GST_VIDEO_OVERLAY(vsink));
gst_video_overlay_expose(GST_VIDEO_OVERLAY(vsink));
gst_object_unref(vsink);
}
// The window did not change, by unreffing it above we unreffed the
// reference we acquired with ANativeWindow_fromSurface as well
return;
}
}
// If we reach this point the window changed and we have to set the new handle
if (jnictx->gst.pipeline != NULL)
{
GstElement* vsink = gst_bin_get_by_name(jnictx->gst.pipeline, "vr_sink");
jnictx->gst.surface_win = new_window;
gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(vsink), (guintptr) new_window);
gst_object_unref(vsink);
}
}
用于设置glimagesink的代码来自例如发现here。我应该补充说,管道没有在别处被引用,我也不会在任何地方访问它,而不检查它是否为NULL。
我不确定这是否相关,但gstreamer住在它自己的线程中,它使用GMainLoop
。管道在该线程内部创建,并在GMainLoop
退出时释放。我认为GLES和Android上的线程很棘手,所以也许......?
无论如何,如果有人可以帮助,我会很感激!如果你需要更多的代码,请让我知道。