# VideoRender
**Repository Path**: harmonyos_samples/video-render
## Basic Information
- **Project Name**: VideoRender
- **Description**: 该示例主要是用来指导如何通过视频解码进行画面渲染,包括基于XComponent渲染、基于OpenGL渲染、基于Vulkan渲染。
- **Primary Language**: Unknown
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 4
- **Forks**: 3
- **Created**: 2025-08-06
- **Last Updated**: 2025-12-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Video Render
## Overview
This sample demonstrates how to render and play videos after decoding based on XComponent, OpenGL, and Vulkan. It helps you build custom players and understand the entire process from video decoding to rendering.
## Effect
| Home Page | XComponent-based Playback Page |
|-----------------------------------------------------|---------------------------------------------------------|
|
|
|
| OpenGL-based Playback Page | Vulkan-based Playback Page |
|
|
|
## How to Use
Tap Video Render Based on XComponent, Video Render Based on OpenGL, or Video Render Based on Vulkan, and tap Play to render and play the video.
## Project Directory
```
├───entry/src/main/cpp
│ ├───capbilities
│ │ ├───include
│ │ │ ├───SampleInfo.h // Video sample
│ │ │ ├───SampleCallback.h // Video callback
│ │ │ ├───Demuxer.h // Media demuxer
│ │ │ └───VideoDecoder.h // Video decoder
│ │ └───src
│ │ ├───SampleCallback.cpp // Video callback
│ │ ├───Demuxer.cpp // Media demuxer
│ │ └───VideoDecoder.cpp // Video decoder
│ ├───player
│ │ ├───include
│ │ │ └───Player.h // Video player
│ │ ├───src
│ │ │ └───Player.cpp // Video player
│ └───render
│ ├───include
│ │ ├───OpenGLRender.h // OpenGL rendering context
│ │ ├───OpenGLRenderThread.h // OpenGL rendering thread
│ │ ├───PluginManager.h // XComponent management
│ │ ├───PluginRender.h // Rendering management
│ │ ├───ShaderProgram.h // Shader
│ │ ├───VulkanRender.h // Vulkan rendering context
│ │ └───VulkanRenderThread.h // Vulkan rendering thread
│ └───src
│ ├───OpenGLRender.cpp // OpenGL rendering context
│ ├───OpenGLRenderThread.cpp // OpenGL rendering thread
│ ├───PluginManager.cpp // XComponent management
│ ├───PluginRender.cpp // Rendering management
│ ├───ShaderProgram.cpp // OpenGL shader
│ ├───VulkanRender.cpp // Vulkan rendering context
│ └───VulkanRenderThread.cpp // Vulkan rendering thread
├───entry/src/main/ets
│ ├───entryability
│ │ └-──EntryAbility.ets // EntryAbility lifecycle callbacks
│ ├───entrybackupability
│ │ └───EntryBackupAbility.ets // EntryBackupAbility lifecycle callbacks
│ └───pages
│ ├───OpenGLPlayer.ets // OpenGL playback page
│ ├───Index.ets // Home page
│ ├───VulkanPlayer.ets // Vulkan playback page
│ └───XComponentPlayer.ets // XComponent playback page
└───entry/src/main/resources // Resources
```
## How to Implement
### Video Rendering Based on XComponent
1. When the XComponent is created, obtain its NativeWindow object via the OnSurfaceCreatedCB callback.
2. Implement basic codec features, including the demuxer and decoder.
3. Implement playback features, and start the input and output child threads.
4. In the decoding input child thread, use the demuxer to read video data and submit it to the decoder.
5. In the decoding output child thread, submit the decoded data to the output surface.
### Video Rendering Based on OpenGL
1. Implement OpenGL rendering child threads, including basic capabilities such as initializing the OpenGL environment, creating a surface, and initializing NativeImage.
2. Create a NativeImage object and obtain the NativeWindow object.
3. When the XComponent is created, obtain its NativeWindow object via the OnSurfaceCreatedCB callback. OpenGL then creates a surface via the XComponent's NativeWindow object.
4. Implement basic codec features, including the demuxer and decoder.
5. Implement playback features, and start the input and output child threads.
6. In the decoding input child thread, use the demuxer to read video data and submit it to the decoder.
7. In the decoding output child thread, submit the decoded data to the output surface, specifically, the NativeWindow object of NativeImage.
8. Update the video frame buffer to the OpenGL texture via NativeImage.
9. Call eglSwapBuffers to submit the rendered buffer to the XComponent's NativeWindow object.
### Video Rendering Based on Vulkan
1. Create a rendering child thread. When the child thread is started, load the Vulkan dynamic link library.
2. Create a NativeImage object and obtain the NativeWindow object.
3. When the XComponent is created, obtain its NativeWindow object via the OnSurfaceCreatedCB callback. Vulkan then creates a surface via the XComponent's NativeWindow object.
4. Implement basic codec features, including the demuxer and decoder.
5. Implement playback features, and start the input and output child threads.
6. In the decoding input child thread, use the demuxer to read video data and submit it to the decoder.
7. In the decoding output child thread, submit the decoded data to the output surface, specifically, the NativeWindow object of NativeImage.
8. Once NativeImage has available data, retrieve the video data by calling OH_NativeImage_AcquireNativeWindowBuffer(), and convert it to NativeBuffer type using OH_NativeBuffer_FromNativeWindowBuffer().
9. After obtaining the NativeBuffer, Vulkan converts the format to RGBA and renders the video data.
## Required Permissions
N/A
## Constraints
1. This sample is only supported on Huawei phones running standard systems.
2. The HarmonyOS version must be HarmonyOS 5.1.1 Release or later.
3. The DevEco Studio version must be DevEco Studio 5.1.1 Release or later.
4. The HarmonyOS SDK version must be HarmonyOS 5.1.1 Release SDK or later.