(七)c.1:SDL双线程 提高播放帧率

这是一个大框架,目前c.1已经完成左边主线程视频流的设计,右边音频也已经完成,不过我还没有添加到c.1代码中。

之前c.0的代码思路是:1读取一视频帧,然后2映射贴图,最后3显示;在映射贴图(视频处理)中是采用双线程,加载到GPU进行计算,不过后来我测试了一下三个部分占用的时间比,1和3占比四分之一,2占比二分之一,这还是在加载到GPU计算的结果,所以导致最后播放帧率只有22左右,不满足30帧率的要求。

c.1的代码思路就如上图所示,一个线程预存视频帧,我测试过这个预存也就是读取每一帧到一个固定buff中的时间较短,所以等预存满了再和视频帧处理显示线程同步,这样相当于本来花在1 2 3上时间最终只花了2 3的时间,测得的帧率基本在30以上。
主要是增加了一下函数和一些地方的改动:
int LoadFrame(void*xx) {//预加载线程
	while (1) {
		frame = cvQueryFrame(capture);//读取下一帧
		if (!frame) break;
		if ((Mbuff1 + 1) % MaxLoadFrameBuffSize == Mbuff2)
			while (1) {//同步处理 满队列等待
				//waitKey(Sleepms);
				if ((Mbuff1 + 1) % MaxLoadFrameBuffSize != Mbuff2) break;
			}
		cvarrToMat(frame).copyTo(Mbuff[Mbuff1]);//帧转换成MAT格式保存在Mbuff中
		Mbuff1 = (Mbuff1 + 1) % MaxLoadFrameBuffSize;//入队
	}
	return 0;
}
void MPop() {//出队列
	picture_remap.rgbImg = Mbuff[Mbuff2];
	if (Mbuff2 != Mbuff1)
		Mbuff2 = (Mbuff2 + 1) % MaxLoadFrameBuffSize;
}
void SetupRC()
{
	int i;

	glGenTextures(1, &cubeTexture);
	glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTexture);

	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

	frame = cvQueryFrame(capture);//
	MatInit();//
	SDL_Delay(5000);//
	MPop();//
	remap6();//

	gltMakeCube(cubeBatch, 16.0f);

	skyBoxShader = gltLoadShaderPairWithAttributes("SkyBox.vp", "SkyBox.fp", 2,
		GLT_ATTRIBUTE_VERTEX, "vVertex",
		GLT_ATTRIBUTE_NORMAL, "vNormal");

	locMVPSkyBox = glGetUniformLocation(skyBoxShader, "mvpMatrix");
}

void CMainApplication::RunMainLoop()
{
	bool bQuit = false;

	SDL_StartTextInput();
	SDL_ShowCursor(SDL_DISABLE);
	//
	int ct = 0;
	DWORD start_time, end_time, q, p;
	start_time = GetTickCount();

	//
	while (!bQuit)
	{
		//bQuit = HandleInput();
		RenderFrame();//显示

		MPop();//出队列
		remap6();//贴图映射

		if (++ct == 30)
		{
			ct = 0;
			end_time = GetTickCount();
			printf("播放帧率 %f \n", 30000.0 / (end_time - start_time));
			start_time = end_time;
		}
	}

	SDL_StopTextInput();
}

 
 
int main(int argc, char *argv[]) { capture = cvCreateFileCapture(VideoAddr); QueryPerformanceFrequency(&nFreq); picture_remap.rgbImg.setDefaultAllocator(cv::cuda::HostMem::getAllocator(cv::cuda::HostMem::AllocType::PAGE_LOCKED)); picture_remap.rgbImg.create(picture_remap.rgbImg.rows, picture_remap.rgbImg.cols, CV_8UC3); double rate = (double)cvGetCaptureProperty(capture, CV_CAP_PROP_FPS); printf("原始帧率 %f \n", rate); int frames = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT); thread = SDL_CreateThread(LoadFrame, "LoadFrame", &xx);//预加载线程 SDL_Delay(1000);//等加载线程至少加载一帧图片 MPop();//出队列
src[1].upload(picture_remap.rgbImg, src_stream[1]); CMainApplication *pMainApplication = new CMainApplication(argc, argv); if (!pMainApplication->BInit()) { pMainApplication->Shutdown(); return 1; } pMainApplication->RunMainLoop(); pMainApplication->Shutdown(); return 0; }


猜你喜欢

转载自blog.csdn.net/qq_24854861/article/details/80035914