本文原创发布在华为开发者社区。
介绍
本示例基于OpenGL对相机流进行处理操作,然后通过Xcomponen渲染显示相机,实现相机的录制、播放视频功能。
效果预览
使用说明
使用OpenGL的相关能力,需要添加相关动态链接库和头文件。
实现思路
- 添加XComponent组件,在native侧通过OH_NativeXComponent_RegisterCallback注册XComponent回调;
// 调用触摸事件回调
renderCallback_.DispatchTouchEvent = DispatchTouchEventCB;
OH_NativeXComponent_RegisterCallback(nativeXComponent, &renderCallback_);
- 在napi 接口init的时候在Xcomponent的OnSurfaceCreatedCB回调中初始化渲染线程,通过OH_NativeImage_Create创建nativeImage;
void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window)
{
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceCreatedCB");
if ((component == nullptr) || (window == nullptr)) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback",
"OnSurfaceCreatedCB: component or window is null");
return;
}
char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = { '\0' };
uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback",
"OnSurfaceCreatedCB: Unable to get XComponent id");
return;
}
std::string id(idStr);
auto render = PluginRender::GetInstance(id);
uint64_t width;
uint64_t height;
int32_t xSize = OH_NativeXComponent_GetXComponentSize(component, window, &width, &height);
if ((xSize != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) || (render == nullptr)) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback",
"OnSurfaceCreatedCB: Unable to get XComponent size");
return;
}
if (render != nullptr) {
render->UpdateNativeWindow(window, width, height);
}
}
- 通过OH_NativeImage_GetSurfaceId获取surfaceID并传递到arkts侧;
{
std::lock_guard<std::mutex> lock(nativeImageSurfaceIdMutex_);
nativeImageWindow_ = OH_NativeImage_AcquireNativeWindow(nativeImage_);
ret = OH_NativeImage_GetSurfaceId(nativeImage_, &nativeImageSurfaceId_);
}
- 通过OH_NativeImage_SetOnFrameAvailableListener设置帧可用回调,通过NativeVsync接收系统信号,控制渲染;
nativeImageFrameAvailableListener_.context = this;
nativeImageFrameAvailableListener_.onFrameAvailable = &RenderThread::OnNativeImageFrameAvailable;
ret = OH_NativeImage_SetOnFrameAvailableListener(nativeImage_, nativeImageFrameAvailableListener_);
- 通过OH_NativeImage_UpdateSurfaceImage获取最新帧更新相关联的OpenGL ES纹理,通过eglSwapBuffers将纹理渲染上屏
OH_NativeImage_AttachContext(nativeImage_, nativeImageTexId_);
int32_t ret = OH_NativeImage_UpdateSurfaceImage(nativeImage_);
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。