Windows TRTC 使用OpenGL自定义渲染

2021-10-11 10:40:29 浏览数 (1)

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

0 人点赞