我尝试在其他平台上使用Gstreamer在Android上显示视频:
gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(video_sink), this->ui->playback_widget->winId());
//playback_widget - QOpenGLWidget
但我认为winId()会返回其他东西而不是ANativeWindow,因为我得到了:
F libc:致命信号11(SIGSEGV),代码1,故障地址0x5e in tid 3154(gstglcontext)
那么,如何从Android上的某些Qt小部件获取ANativeWindow的实例(或指针)?
答案 0 :(得分:0)
支持嵌入本机小部件是不完整的,并不总是有效。请记住,Qt可能会创建本机句柄,但它们不一定代表实际的本机窗口。此外,QWidget::winId()
没有提供可移植性的有效保证,只是标识符是唯一的:
原则上是便携式的,但是如果你使用它,你可能会做一些不便携的事情。小心。
原因是WId
实际上是typedef
的{{1}}。
解决方案:您至少需要将quintptr
的回复转换为winId
,,假设这是基础窗口句柄类型, Qt用于识别本机窗口。
This solution似乎针对的是X Windows,但可能会提供一些指导。
另请参阅QWidget::effectiveWinId()
和QWidget::nativeParentWidget()
的文档以获取更多有用的背景信息。
更新:Per the platform notes,使用OpenGL + Qt + Android时有一些注意事项,包括:
平台插件仅支持全屏顶级OpenGL窗口。
答案 1 :(得分:0)
在@ don-prog的答案和一些阅读时间后,我可以使它工作。这是我的代码。请注意:我必须延迟此代码执行,直到Qt完成加载视图和布局。
以下代码检索QtActivity Java对象,然后深入查看视图和布局对象,直到QtSurface - 扩展了android.view.SurfaceView。然后它要求SurfaceHolder最终得到我们需要调用ANativeWindow_fromSurface的Surface对象。
QPlatformNativeInterface *nativeInterface = QApplication::platformNativeInterface();
jobject activity = (jobject)nativeInterface->nativeResourceForIntegration("QtActivity");
QAndroidJniEnvironment * qjniEnv;
JNIEnv * jniEnv;
JavaVM * jvm = qjniEnv->javaVM();
jvm->GetEnv(reinterpret_cast<void**>(&qjniEnv), JNI_VERSION_1_6);
jvm->AttachCurrentThread(&jniEnv,NULL);
jint r_id_content = QAndroidJniObject::getStaticField<jint>("android/R$id", "content");
QAndroidJniObject view = ((QAndroidJniObject) activity).callObjectMethod("findViewById", "(I)Landroid/view/View;", r_id_content);
if (view.isValid()) {
QAndroidJniObject child1 = view.callObjectMethod("getChildAt", "(I)Landroid/view/View;", 0);
QAndroidJniObject child2 = child1.callObjectMethod("getChildAt", "(I)Landroid/view/View;", 0);
if (child2.isValid()) {
QAndroidJniObject sHolder = child2.callObjectMethod("getHolder","()Landroid/view/SurfaceHolder;");
if (sHolder.isValid()) {
QAndroidJniObject theSurface = sHolder.callObjectMethod("getSurface","()Landroid/view/Surface;");
if (theSurface.isValid()) {
ANativeWindow* awindow = ANativeWindow_fromSurface(jniEnv, theSurface.object());
qDebug() << "This is a ANativeWindow " << awindow;
}
}
} else {
qDebug() << "Views are not loaded yet or you are not in the Qt UI Thread";
}
}
希望它可以帮助其他人