Преглед изворни кода

Z991239-2465 #comment other: 优化视频回显库结构,兼容windows版

陈礼鹏80274480 пре 4 година
родитељ
комит
81bc4ca5ba

+ 2 - 3
Module/mod_localmediaplay/mod_localmediaplay.cpp

@@ -919,10 +919,10 @@ void* StartMediaPlayFunc(void* param)
 				config.nPlayInterval = item.playInterval;
 				// add by ly@2018/07/30
 				//config.nVolume = IS_DEBUG ? 0 : entity->m_defaultVolum;
-				if (!entity->GetLocalVideoVolume(0, config.nVolume))
-				{
+				if (!entity->GetLocalVideoVolume(0, config.nVolume)){
 					config.nVolume = entity->m_defaultVolum;
 				}
+				
 				//Dbg("config.nVolume=%d while play local video.", config.nVolume);
 				config.nWndX = entity->m_mediaParam.nWndX;
 				config.nWndY = entity->m_mediaParam.nWndY;
@@ -932,7 +932,6 @@ void* StartMediaPlayFunc(void* param)
 				strncpy(config.strFileNames[0], item.strvideoNames, strlen(item.strvideoNames));
 				strncpy(config.strVideoRunTime_S, "09:00:00", sizeof(config.strVideoRunTime_S));
 				strncpy(config.strVideoRunTime_E, "17:30:00", sizeof(config.strVideoRunTime_E));
-				entity->m_pMediaPlayer[entity->m_mediaParam.nCfgInx]->PlayMedia(config);
 				if (-2 == entity->m_pMediaPlayer[entity->m_mediaParam.nCfgInx]->PlayMedia(config)){
 					Sleep(DEFAULT_SLEEP_TIME);
 					continue;

+ 1 - 2
Other/libmediadeviceinfo/linux/videodevice_info_linux.cpp

@@ -286,8 +286,7 @@ int  rvc_videocap_get_video_device_id(const char* dev_name)
 		char strfullname[2*MAX_PATH] = { 0 };
 		if (0 == rvc_videocap_get_device_fullpathname(i, strfullname, 2 * MAX_PATH)){
 			ifound++;
-			if (0 == strcasecmp(strfullname, dev_name))
-			{
+			if (0 == strcasecmp(strfullname, dev_name)){
 				iret = i;
 				break;
 			}

+ 2 - 2
Other/libvideorender/CMakeLists.txt

@@ -12,8 +12,8 @@ endif(RVC_DEBUG_MODE)
 set(${MODULE_PREFIX}_SRCS
     ivideorenderinterface.h
 	ivideorenderinterface.cpp
-	libvideorender.h
-	libvideorender.cpp
+	./linux/videorender_linux.h
+	./linux/videorender_linux.cpp
 )
 
 add_library(${MODULE_NAME} SHARED ${${MODULE_PREFIX}_SRCS})

+ 1 - 1
Other/libvideorender/ivideorenderinterface.cpp

@@ -1,5 +1,5 @@
 #include "ivideorenderinterface.h"
-#include "libvideorender.h"
+#include "./linux/videorender_linux.h"
 
 
 IVideoRender* CreateVideoRenderObj(IRenderCallback* pCallback)

+ 332 - 0
Other/libvideorender/linux/videorender_linux.cpp

@@ -0,0 +1,332 @@
+#include"videorender_linux.h"
+#include "../../libvideoframework/videoutil.h"
+
+
+VideoRenderImpl::VideoRenderImpl(IRenderCallback* pCallback)
+{
+	m_sdl_window = NULL;
+	m_rending_texture = NULL;
+	m_renderer = NULL;
+	m_callback = pCallback;
+
+	m_cx = SDL_WINDOWPOS_UNDEFINED;
+	m_cy = SDL_WINDOWPOS_UNDEFINED;
+	m_width = 0;
+	m_height = 0;
+	m_videoformat = VIDEO_FORMAT_RGB24;
+	m_flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS | SDL_WINDOW_HIDDEN | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_SKIP_TASKBAR | SDL_WINDOW_POPUP_MENU;
+	m_convertbuffer = NULL;
+}
+
+
+VideoRenderImpl::~VideoRenderImpl()
+{
+	if (NULL != m_rending_texture) {
+		SDL_DestroyTexture(m_rending_texture);
+		m_rending_texture = NULL;
+	}
+
+	if (NULL != m_renderer) {
+		SDL_DestroyRenderer(m_renderer);
+		m_renderer = NULL;
+	}
+
+	if (NULL != m_sdl_window) {
+		SDL_DestroyWindow(m_sdl_window);
+		m_sdl_window = NULL;
+	}
+
+	if (NULL != m_convertbuffer){
+		delete []m_convertbuffer;
+		m_convertbuffer = NULL;
+	}
+		
+	SDL_Quit();
+}
+
+int VideoRenderImpl::SetWindowProperty(videorender_param_t* tparam)
+{
+	int  iRet = -1;
+	if (NULL == tparam){
+		return iRet;
+	}
+
+	m_cx = tparam->icx;
+	m_cy = tparam->icy;
+	m_width = tparam->uwidth;
+	m_height = tparam->uheight;
+	m_videowidth = m_width;
+	m_videoheight = m_height;
+	if (tparam->uvideowidth > 0){
+		m_videowidth = tparam->uvideowidth;
+	}
+
+	if (tparam->uvideoheight > 0){
+		m_videoheight = tparam->uvideoheight;
+	}
+
+	m_flags |= tparam->uwinflags;
+
+	m_videoformat = tparam->ivideoformat;
+
+	if (VIDEO_FORMAT_RGB24 == m_videoformat){
+		m_convertbuffer = new unsigned char[m_videowidth* m_videoheight*4];
+	}
+
+	iRet = 0;
+
+	return iRet;
+}
+
+SDL_PixelFormatEnum VideoRenderImpl::GetPixelFormat()
+{
+	SDL_PixelFormatEnum eType = SDL_PIXELFORMAT_BGR24;
+	//SDL_PixelFormatEnum eType = SDL_PIXELFORMAT_BGR888;
+	if (VIDEO_FORMAT_I420 == m_videoformat){
+		eType = SDL_PIXELFORMAT_IYUV;
+	}
+
+	return eType;
+}
+
+int VideoRenderImpl::VideoRenderSetParam(videorender_param_t* tparam)
+{
+	if (SetWindowProperty(tparam)){
+		m_callback->Debug("SetWindowProperty failed for param error.");
+		return -1;
+	}
+
+	if (NULL == m_sdl_window){
+		if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0){
+			m_callback->Debug("RENDER: Couldn't initialize SDL2: %s", SDL_GetError());
+			return -1;
+		}
+
+		SDL_SetHint("SDL_HINT_RENDER_SCALE_QUALITY", "1");
+
+		m_sdl_window = SDL_CreateWindow(
+			"rvc video",    // window title
+			m_cx,           // initial x position
+			m_cy,           // initial y position
+			m_width,        // width, in pixels
+			m_height,       // height, in pixels
+			m_flags
+		);
+
+		if (NULL == m_sdl_window){
+			m_callback->Debug("RENDER: (SDL2) Couldn't open window: %s", SDL_GetError());
+			VideoRenderDestroy();
+			return -2;
+		}
+
+		int display_index = SDL_GetWindowDisplayIndex(m_sdl_window);
+		SDL_DisplayMode display_mode;
+		int err = SDL_GetDesktopDisplayMode(display_index, &display_mode);
+		if (0 == err){
+			m_callback->Debug("RENDER: video display %i ->  %dx%dpx @ %dhz",
+					display_index,
+					display_mode.w,
+					display_mode.h,
+					display_mode.refresh_rate);
+		}
+		else {
+			m_callback->Debug("RENDER: Couldn't determine display mode for video display %i", display_index);
+		}
+
+		if (m_width > display_mode.w) {
+			m_width = display_mode.w;
+		}
+		if (m_height > display_mode.h) {
+			m_height = display_mode.h;
+		}
+
+		SDL_SetWindowSize(m_sdl_window, m_width, m_height);
+	}
+
+	/* Allocate a renderer info struct*/
+	SDL_RendererInfo* rend_info = (SDL_RendererInfo*)malloc(sizeof(SDL_RendererInfo));
+	if (NULL == rend_info){
+		m_callback->Debug("RENDER: Couldn't allocate memory for the renderer info data structure");
+		VideoRenderDestroy();
+		return -5;
+	}
+	
+	/* Print the list of the available renderers*/
+	m_callback->Debug("RENDER: Available SDL2 rendering drivers:");
+	for (int i = 0; i < SDL_GetNumRenderDrivers(); i++){
+		if (SDL_GetRenderDriverInfo(i, rend_info) < 0){
+			m_callback->Debug("Couldn't get SDL2 render driver information: %s", SDL_GetError());
+		}
+		else {
+			m_callback->Debug(" %2d: %s", i, rend_info->name);
+			//m_callback->Debug("    SDL_RENDERER_TARGETTEXTURE [%c]", (rend_info->flags & SDL_RENDERER_TARGETTEXTURE) ? 'X' : ' ');
+			//m_callback->Debug("    SDL_RENDERER_SOFTWARE      [%c]", (rend_info->flags & SDL_RENDERER_SOFTWARE) ? 'X' : ' ');
+			//m_callback->Debug("    SDL_RENDERER_ACCELERATED   [%c]", (rend_info->flags & SDL_RENDERER_ACCELERATED) ? 'X' : ' ');
+			//m_callback->Debug("    SDL_RENDERER_PRESENTVSYNC  [%c]", (rend_info->flags & SDL_RENDERER_PRESENTVSYNC) ? 'X' : ' ');
+		}
+	}
+	free(rend_info);
+
+	m_renderer = SDL_CreateRenderer(m_sdl_window, -1,
+		SDL_RENDERER_TARGETTEXTURE |
+		SDL_RENDERER_PRESENTVSYNC |
+		SDL_RENDERER_ACCELERATED);
+
+	if (m_renderer == NULL)
+	{
+		m_callback->Debug("RENDER: (SDL2) Couldn't get a accelerated renderer: %s", SDL_GetError());
+		m_callback->Debug("RENDER: (SDL2) trying with a software renderer");
+
+		m_renderer = SDL_CreateRenderer(m_sdl_window, -1,
+			SDL_RENDERER_TARGETTEXTURE |
+			SDL_RENDERER_SOFTWARE);
+
+		if (m_renderer == NULL)
+		{
+			m_callback->Debug("RENDER: (SDL2) Couldn't get a software renderer: %s", SDL_GetError());
+			m_callback->Debug("RENDER: (SDL2) giving up...");
+			VideoRenderDestroy();
+			return -3;
+		}
+	}
+	
+	/* Allocate a renderer info struct*/
+	SDL_RendererInfo* render_info = (SDL_RendererInfo*)malloc(sizeof(SDL_RendererInfo));
+	if (NULL == render_info){
+		m_callback->Debug("RENDER: Couldn't allocate memory for the renderer info data structure");
+		VideoRenderDestroy();
+		return -5;
+	}
+	
+	/* Print the name of the current rendering driver */
+	if (SDL_GetRendererInfo(m_renderer, render_info) < 0){
+		m_callback->Debug("Couldn't get SDL2 rendering driver information: %s", SDL_GetError());
+	}
+	m_callback->Debug("RENDER: rendering driver in use: %s", render_info->name);
+	//m_callback->Debug("    SDL_RENDERER_TARGETTEXTURE [%c]", (render_info->flags & SDL_RENDERER_TARGETTEXTURE) ? 'X' : ' ');
+	//m_callback->Debug("    SDL_RENDERER_SOFTWARE      [%c]", (render_info->flags & SDL_RENDERER_SOFTWARE) ? 'X' : ' ');
+	//m_callback->Debug("    SDL_RENDERER_ACCELERATED   [%c]", (render_info->flags & SDL_RENDERER_ACCELERATED) ? 'X' : ' ');
+	//m_callback->Debug("    SDL_RENDERER_PRESENTVSYNC  [%c]", (render_info->flags & SDL_RENDERER_PRESENTVSYNC) ? 'X' : ' ');
+
+	free(render_info);
+
+	SDL_RenderSetLogicalSize(m_renderer, m_videowidth, m_videoheight);
+	SDL_SetRenderDrawBlendMode(m_renderer, SDL_BLENDMODE_NONE);
+
+	m_rending_texture = SDL_CreateTexture(m_renderer,
+		GetPixelFormat(),
+		SDL_TEXTUREACCESS_STREAMING,
+		m_videowidth,
+		m_videoheight);
+
+	if (m_rending_texture == NULL){
+		m_callback->Debug("RENDER: (SDL2) Couldn't get a texture for rendering: %s", SDL_GetError());
+		VideoRenderDestroy();
+		return -4;
+	}
+
+	return 0;
+}
+
+
+int VideoRenderImpl::StartVideoRender()
+{
+	return 0;
+}
+
+int VideoRenderImpl::ShowVideoWindow()
+{
+	int iret = -1;
+	if (NULL != m_sdl_window){
+		SDL_ShowWindow(m_sdl_window);
+		iret = 0;
+	}
+	return iret;
+}
+
+int VideoRenderImpl::HideVideoWindow()
+{
+	int iret = -1;
+	if (NULL != m_sdl_window) {
+		SDL_HideWindow(m_sdl_window);
+		iret = 0;
+	}
+	return iret;
+}
+
+
+int VideoRenderImpl::StopVideoRender()
+{
+	HideVideoWindow();
+	return 0;
+}
+
+
+void VideoRenderImpl::VideoRenderDestroy()
+{
+	delete this;
+}
+
+
+int VideoRenderImpl::RenderVideoFrame(video_frame* pframe)
+{
+	int iret = -1;
+	if (NULL == m_sdl_window || NULL == pframe || NULL == m_renderer || NULL == m_rending_texture){
+		return iret;
+	}
+
+	SDL_SetRenderDrawColor(m_renderer, 0, 0, 0, 255); /*black*/
+	SDL_RenderClear(m_renderer);
+
+	/* since data is continuous we can use SDL_UpdateTexture
+	 * instead of SDL_UpdateYUVTexture.
+	 * no need to use SDL_Lock/UnlockTexture (it doesn't seem faster)
+	 */
+	//SDL_QueryTexture()
+
+	if (VIDEO_FORMAT_RGB24 == pframe->format){
+		//ConVert24to32(pframe->data[0], m_convertbuffer, pframe->width, pframe->height);
+		SDL_UpdateTexture(m_rending_texture, NULL, pframe->data[0], pframe->width*3);
+		SDL_Point point = {m_videowidth/2, m_videoheight/2};
+		SDL_RenderCopyEx(m_renderer, m_rending_texture, NULL, NULL, 0, &point, SDL_FLIP_VERTICAL);
+	}
+	else if(VIDEO_FORMAT_I420 == pframe->format){
+		SDL_UpdateTexture(m_rending_texture, NULL, pframe->data[0], pframe->width);
+		SDL_RenderCopy(m_renderer, m_rending_texture, NULL, NULL);
+	}
+	else
+	{
+		m_callback->Debug("%s:%d not support format, return", __FUNCTION__, __LINE__);
+		return iret;
+	}
+
+	SDL_RenderPresent(m_renderer);
+
+	iret = 0;
+
+	return iret;
+}
+
+
+void VideoRenderImpl::ConVert24to32(unsigned char* image_in, unsigned char* image_out, int w, int h) 
+{
+	for (int i = 0; i < h; i++)
+		for (int j = 0; j < w; j++) {
+			//Big Endian or Small Endian?
+			//"ARGB" order:high bit -> low bit.
+			//ARGB Format Big Endian (low address save high MSB, here is A) in memory : A|R|G|B
+			//ARGB Format Little Endian (low address save low MSB, here is B) in memory : B|G|R|A
+			if (SDL_BYTEORDER == SDL_LIL_ENDIAN) {
+				//Little Endian (x86): R|G|B --> B|G|R|A
+				image_out[(i * w + j) * 4 + 0] = image_in[(i * w + j) * 3 + 2];
+				image_out[(i * w + j) * 4 + 1] = image_in[(i * w + j) * 3 + 1];
+				image_out[(i * w + j) * 4 + 2] = image_in[(i * w + j) * 3];
+				image_out[(i * w + j) * 4 + 3] = '0';
+			}
+			else {
+				//Big Endian: R|G|B --> A|R|G|B
+				image_out[(i * w + j) * 4] = '0';
+				memcpy(image_out + (i * w + j) * 4 + 1, image_in + (i * w + j) * 3, 3);
+			}
+		}
+}

+ 45 - 0
Other/libvideorender/linux/videorender_linux.h

@@ -0,0 +1,45 @@
+#pragma once
+
+#include "../ivideorenderinterface.h"
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_video.h>
+#include <SDL2/SDL_render.h>
+#include <SDL2/SDL_rect.h>
+#include <SDL2/SDL_mutex.h>
+
+
+class VideoRenderImpl : public IVideoRender
+{
+public:
+	VideoRenderImpl(IRenderCallback* pCallback);
+	~VideoRenderImpl();
+
+	int VideoRenderSetParam(videorender_param_t* tparam);
+	int StartVideoRender();
+	int StopVideoRender();
+	void VideoRenderDestroy();
+	int ShowVideoWindow();
+	int HideVideoWindow();
+	int RenderVideoFrame(video_frame* pframe);
+
+	int SetWindowProperty(videorender_param_t* tparam);
+	SDL_PixelFormatEnum GetPixelFormat();
+	void ConVert24to32(unsigned char* image_in, unsigned char* image_out, int w, int h);
+
+
+private:
+	SDL_Window* m_sdl_window;
+	SDL_Texture* m_rending_texture;
+	SDL_Renderer* m_renderer;
+	IRenderCallback* m_callback;
+	unsigned char* m_convertbuffer;
+
+	int m_cx;
+	int m_cy;
+	uint32_t m_videowidth;
+	uint32_t m_videoheight;
+	uint32_t m_width;
+	uint32_t m_height;
+	uint32_t m_flags;
+	int m_videoformat;
+};