Windows TRTC 使用OpenGL自定义渲染,将视频数据渲染到您的3D游戏或工程中。
一. 准备开发环境
1.OpenGL开发环境
参见:创建窗口 - LearnOpenGL CN (learnopengl-cn.github.io)
2.TRTC集成
参见:实时音视频 快速集成(Windows) - 快速入门 - 文档中心 - 腾讯云 (tencent.com)
二. 编写代码
代码主要流程为:创建窗口->创建TRTC实例并设置自定义渲染回调->创建OpenGL纹理->在渲染回调中将图像数据复制出来,主线程绘制更新纹理。
注意:由于OpenGL是基于单线程设计的接口,调用的时候请在OpenGLContext线程中(一般为主线程)进行OpenGL相关操作
伪代码如下:
代码语言:c 复制int main(){
//初始化
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//创建窗口
auto win = glfwCreateWindow(....);
//设置当前主要上下文
glfwMakeContextCurrent(win);
//
if (gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
GLuint gluiTextureID = 0;
//创建纹理
glGenTextures(1, &gluiTextureID);
... 其他相关操作
//创建TRTC对象,设置渲染回调
MyTRTCVideoRenderCallback stLocaRender;
ITRTCCloud* trtc = getTRTCShareInstance();
trtc->setLocalVideoRenderCallback(TRTCVideoPixelFormat::TRTCVideoPixelFormat_BGRA32,
TRTCVideoBufferType::TRTCVideoBufferType_Buffer, &stLocaRender);
trtc->startLocalPreview(NULL);
while (!glfwWindowShouldClose(frame)){
//TODO 进行渲染
}
destroyTRTCShareInstance();
... 其他相关操作
glDeleteTextures(1,&gluiTextureID);
}
return 0;
}
上面说到,由于OpenGL是基于单线程设计的接口,调用的时候请在OpenGLContext线程中(一般为主线程)进行OpenGL相关操作。我们需要在主线程来进行更新纹理对象:
代码语言:c 复制std::mutex g_TextureMtx;
bool needUpdateTexture = false;
TRTCVideoFrame trtcFrame;
//....code
int main(){
//.....code
while (!glfwWindowShouldClose(frame))
{
g_TextureMtx.lock();
if (needUpdateTexture) {
frameWidth = trtcFrame.width;
frameHeight = trtcFrame.height;
stTexture2D.texImage(trtcFrame.width, trtcFrame.height, GL_RGBA, (GLubyte*)trtcFrame.data);
needUpdateTexture = false;
}
g_TextureMtx.unlock();
//code....
}
.....
}
在自定义渲染回调中直接拷贝数据,交给主线程处理即可,最好不要在此回调中进行耗时操作:
代码语言:javascript复制 //在自定义渲染回调中直接转换并拷贝数据到trtcFrame
virtual void MyTRTCVideoRenderCallback::onRenderVideoFrame(const char* userId, TRTCVideoStreamType streamType, TRTCVideoFrame* frame) {
if (frame) {
if (frame->bufferType == TRTCVideoBufferType::TRTCVideoBufferType_Buffer &&
frame->videoFormat == TRTCVideoPixelFormat::TRTCVideoPixelFormat_BGRA32)
{
g_TextureMtx.lock();
if (frame->width > 0 && frame->height > 0 && frame->data != NULL)
{
if (trtcFrame.data) delete[] trtcFrame.data;
int dataSize = frame->width * frame->height * 4;
char* data = new char[dataSize];
trtcFrame = (*frame);
trtcFrame.data = data;
//
// 下面BGRA to RGBA
{
unsigned int dataSize = (trtcFrame.width * trtcFrame.height * 4);
for (size_t i = 0; i < dataSize; i = 4)
{
trtcFrame.data[i 0] = frame->data[i 2];
trtcFrame.data[i 1] = frame->data[i 1];
trtcFrame.data[i 2] = frame->data[i 0];
trtcFrame.data[i 3] = frame->data[i 3];
}
}
needUpdateTexture = true;
}
g_TextureMtx.unlock();
}
}
}
OK,完成。
===========================================
项目下载地址:
链接:https://pan.baidu.com/s/1dAUqihfh2mu54U3K4VZVNw
提取码:zsdp