基于OpenGL渲染相机流鸿蒙示例代码

鸿蒙场景化示例代码技术工程师
发布于 2025-2-28 17:09
3.0w浏览
0收藏

本文原创发布在华为开发者社区

介绍

本示例基于OpenGL对相机流进行处理操作,然后通过Xcomponen渲染显示相机,实现相机的录制、播放视频功能。

基于OpenGL渲染相机流源码链接

效果预览

基于OpenGL渲染相机流鸿蒙示例代码-鸿蒙开发者社区

使用说明

使用OpenGL的相关能力,需要添加相关动态链接库和头文件

实现思路

  1. 添加XComponent组件,在native侧通过OH_NativeXComponent_RegisterCallback注册XComponent回调;
    // 调用触摸事件回调
    renderCallback_.DispatchTouchEvent = DispatchTouchEventCB;
    OH_NativeXComponent_RegisterCallback(nativeXComponent, &renderCallback_);
  • 1.
  • 2.
  • 3.
  1. 在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);
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  1. 通过OH_NativeImage_GetSurfaceId获取surfaceID并传递到arkts侧;
    {
        std::lock_guard<std::mutex> lock(nativeImageSurfaceIdMutex_);
        nativeImageWindow_ = OH_NativeImage_AcquireNativeWindow(nativeImage_);
        ret = OH_NativeImage_GetSurfaceId(nativeImage_, &nativeImageSurfaceId_);
    }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  1. 通过OH_NativeImage_SetOnFrameAvailableListener设置帧可用回调,通过NativeVsync接收系统信号,控制渲染;
    nativeImageFrameAvailableListener_.context = this;
    nativeImageFrameAvailableListener_.onFrameAvailable = &RenderThread::OnNativeImageFrameAvailable;
    ret = OH_NativeImage_SetOnFrameAvailableListener(nativeImage_, nativeImageFrameAvailableListener_);
  • 1.
  • 2.
  • 3.
  1. 通过OH_NativeImage_UpdateSurfaceImage获取最新帧更新相关联的OpenGL ES纹理,通过eglSwapBuffers将纹理渲染上屏
    OH_NativeImage_AttachContext(nativeImage_, nativeImageTexId_);

    int32_t ret = OH_NativeImage_UpdateSurfaceImage(nativeImage_);
  • 1.
  • 2.
  • 3.

分类
收藏
回复
举报


回复
    相关推荐