123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- #include"libvideorender.h"
- #include "videoutil.h"
- #include <string.h>
- //Refresh Event
- #ifndef REFRESH_EVENT
- #define REFRESH_EVENT (SDL_USEREVENT + 1)
- #endif
- #ifndef RVC_DEFAULT_DELAY_TIME
- #define RVC_DEFAULT_DELAY_TIME 1
- #endif
- VideoRenderImpl::VideoRenderImpl(videorender_callback_t* pCallback)
- {
- m_sdl_window = NULL;
- m_rending_texture = NULL;
- m_renderer = NULL;
- memcpy(&m_callback, pCallback, sizeof(videorender_callback_t));
- m_refresh_flag = false;
- m_bmoveable = false;
- m_refresh_thread = NULL;
- m_x = SDL_WINDOWPOS_UNDEFINED;
- m_y = SDL_WINDOWPOS_UNDEFINED;
- m_width = 0;
- m_height = 0;
- m_videoformat = VIDEO_FORMAT_RGB24;
- m_flags = SDL_WINDOW_BORDERLESS | SDL_WINDOW_HIDDEN | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_SKIP_TASKBAR | SDL_WINDOW_POPUP_MENU;
- }
- VideoRenderImpl::~VideoRenderImpl()
- {
- if (NULL != m_rending_texture) {
- SDL_DestroyTexture(m_rending_texture);
- m_rending_texture = NULL;
- //RenderLog(RENDER_LOG_DEBUG, "DestroyTexture.");
- }
- if (NULL != m_renderer) {
- SDL_DestroyRenderer(m_renderer);
- m_renderer = NULL;
- //RenderLog(RENDER_LOG_DEBUG, "DestroyRenderer.");
- }
- if (NULL != m_sdl_window) {
- SDL_DestroyWindow(m_sdl_window);
- m_sdl_window = NULL;
- //RenderLog(RENDER_LOG_DEBUG, "DestroyWindow.");
- }
- }
- int VideoRenderImpl::SetWindowProperty(videorender_param_t* tparam)
- {
- int iRet = -1;
- if (NULL == tparam){
- return iRet;
- }
- m_x = tparam->icx;
- m_y = 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_videoformat = tparam->ivideoformat;
- iRet = 0;
- return iRet;
- }
- SDL_PixelFormatEnum VideoRenderImpl::GetPixelFormat()
- {
- SDL_PixelFormatEnum eType = SDL_PIXELFORMAT_BGR24;
- if (VIDEO_FORMAT_I420 == m_videoformat){
- eType = SDL_PIXELFORMAT_IYUV;
- }
- return eType;
- }
- int VideoRenderImpl::VideoRenderSetParam(videorender_param_t* tparam)
- {
- if (SetWindowProperty(tparam)){
- RenderLog(RENDER_LOG_ERROR, "SetWindowProperty failed for param error.");
- return -1;
- }
- if (NULL == m_sdl_window){
- SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");
- m_sdl_window = SDL_CreateWindow(
- "", // window title
- m_x, // initial x position
- m_y, // initial y position
- m_width, // width, in pixels
- m_height, // height, in pixels
- m_flags
- );
- if (NULL == m_sdl_window){
- RenderLog(RENDER_LOG_ERROR, "RENDER: (SDL2) Couldn't open window: %s", SDL_GetError());
- VideoRenderDestroy();
- return -2;
- }
- int idisplay_index = SDL_GetWindowDisplayIndex(m_sdl_window);
- if (-1 == idisplay_index) {
- RenderLog(RENDER_LOG_ERROR, "RENDER: get window dispaly index failed!");
- return -3;
- }
- SDL_DisplayMode display_mode;
- int err = SDL_GetDesktopDisplayMode(idisplay_index, &display_mode);
- if (0 == err){
- RenderLog(RENDER_LOG_DEBUG, "RENDER: video display %i -> %dx%dpx @ %dhz",
- idisplay_index,
- display_mode.w,
- display_mode.h,
- display_mode.refresh_rate);
- }
- else {
- RenderLog(RENDER_LOG_ERROR, "RENDER: Couldn't determine display mode for video display %i", idisplay_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);
- }
- static bool blog = true;
- /* Print the list of the available renderers*/
- if (blog) {
- RenderLog(RENDER_LOG_DEBUG, "RENDER: Available SDL2 rendering drivers:");
- }
- SDL_RendererInfo rend_info;
- for (int i = 0; i < SDL_GetNumRenderDrivers(); i++){
- if (SDL_GetRenderDriverInfo(i, &rend_info) < 0){
- RenderLog(RENDER_LOG_ERROR, "Couldn't get SDL2 render driver information: %s", SDL_GetError());
- }
- else {
- if (blog) {
- RenderLog(RENDER_LOG_DEBUG, " %2d: %s", i, rend_info.name);
- }
- //RenderLog(RENDER_LOG_DEBUG," SDL_RENDERER_TARGETTEXTURE [%c]", (rend_info.flags & SDL_RENDERER_TARGETTEXTURE) ? 'X' : ' ');
- //RenderLog(RENDER_LOG_DEBUG," SDL_RENDERER_SOFTWARE [%c]", (rend_info.flags & SDL_RENDERER_SOFTWARE) ? 'X' : ' ');
- //RenderLog(RENDER_LOG_DEBUG," SDL_RENDERER_ACCELERATED [%c]", (rend_info.flags & SDL_RENDERER_ACCELERATED) ? 'X' : ' ');
- //RenderLog(RENDER_LOG_DEBUG," SDL_RENDERER_PRESENTVSYNC [%c]", (rend_info.flags & SDL_RENDERER_PRESENTVSYNC) ? 'X' : ' ');
- }
- }
- m_renderer = SDL_CreateRenderer(m_sdl_window, -1,
- SDL_RENDERER_TARGETTEXTURE |
- SDL_RENDERER_PRESENTVSYNC |
- SDL_RENDERER_ACCELERATED);
- if (m_renderer == NULL)
- {
- RenderLog(RENDER_LOG_ERROR, "RENDER: (SDL2) Couldn't get a accelerated renderer: %s", SDL_GetError());
- RenderLog(RENDER_LOG_INFO, "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){
- RenderLog(RENDER_LOG_ERROR, "RENDER: (SDL2) Couldn't get a software renderer: %s", SDL_GetError());
- RenderLog(RENDER_LOG_ERROR, "RENDER: (SDL2) giving up...");
- VideoRenderDestroy();
- return -3;
- }
- }
-
- /* Print the name of the current rendering driver */
- SDL_RendererInfo render_info;
- if (SDL_GetRendererInfo(m_renderer, &render_info) < 0){
- RenderLog(RENDER_LOG_ERROR, "Couldn't get SDL2 rendering driver information: %s", SDL_GetError());
- }
- if (blog) {
- RenderLog(RENDER_LOG_DEBUG, "RENDER: rendering driver in use: %s", render_info.name);
- }
- //RenderLog(RENDER_LOG_DEBUG, " SDL_RENDERER_TARGETTEXTURE [%c]", (render_info.flags & SDL_RENDERER_TARGETTEXTURE) ? 'X' : ' ');
- //RenderLog(RENDER_LOG_DEBUG, " SDL_RENDERER_SOFTWARE [%c]", (render_info.flags & SDL_RENDERER_SOFTWARE) ? 'X' : ' ');
- //RenderLog(RENDER_LOG_DEBUG, " SDL_RENDERER_ACCELERATED [%c]", (render_info.flags & SDL_RENDERER_ACCELERATED) ? 'X' : ' ');
- //RenderLog(RENDER_LOG_DEBUG, " SDL_RENDERER_PRESENTVSYNC [%c]", (render_info.flags & SDL_RENDERER_PRESENTVSYNC) ? 'X' : ' ');
- blog = false;
- 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){
- RenderLog(RENDER_LOG_ERROR, "RENDER: (SDL2) Couldn't get a texture for rendering: %s", SDL_GetError());
- VideoRenderDestroy();
- return -4;
- }
- return 0;
- }
- static int refresh_video(void *opaque)
- {
- VideoRenderImpl* pImpl = (VideoRenderImpl*)opaque;
- while (pImpl->GetReFreshFlag()) {
- SDL_Event event;
- event.type = REFRESH_EVENT;
- SDL_PushEvent(&event);
- SDL_Delay(RVC_DEFAULT_DELAY_TIME);
- }
- return 0;
- }
- static SDL_HitTestResult SDLCALL SDL_HitTestCallback(SDL_Window *win, const SDL_Point *area, void *data)
- {
- VideoRenderImpl* pImpl = (VideoRenderImpl*)data;
- int iwidth = 0, iheight = 0;
- SDL_GetWindowSize(win, &iwidth, &iheight);
- pImpl->RenderLog(RENDER_LOG_DEBUG, "window width is %d, height is %d.", iwidth, iheight);
- pImpl->RenderLog(RENDER_LOG_DEBUG, "area->x = %d, area->y = %d.", area->x, area->y);
- return SDL_HITTEST_DRAGGABLE;
- }
- bool VideoRenderImpl::GetReFreshFlag()
- {
- return m_refresh_flag;
- }
- int VideoRenderImpl::StartVideoRender()
- {
- m_refresh_flag = true;
- m_refresh_thread = SDL_CreateThread(refresh_video,"refresh video thread", this);
- if (NULL == m_refresh_thread) {
- RenderLog(RENDER_LOG_ERROR, "SDL_Create refresh video thread failed: %s.", SDL_GetError());
- return -1;
- }
- if (m_bmoveable){
- if (0 != SDL_SetWindowHitTest(m_sdl_window, SDL_HitTestCallback, this)) {
- RenderLog(RENDER_LOG_ERROR, "SDL_SetWindowHitTest failed: %s.", SDL_GetError());
- return -1;
- }
- }
- return 0;
- }
- int VideoRenderImpl::ShowVideoWindow()
- {
- int iret = -1;
- if (NULL != m_sdl_window){
- Uint32 uflags = SDL_GetWindowFlags(m_sdl_window);
- if (uflags & SDL_WINDOW_HIDDEN) {
- SDL_ShowWindow(m_sdl_window);
- }
- iret = 0;
- }
- return iret;
- }
- int VideoRenderImpl::HideVideoWindow()
- {
- int iret = -1;
- if (NULL != m_sdl_window) {
- Uint32 uflags = SDL_GetWindowFlags(m_sdl_window);
- if (uflags & SDL_WINDOW_SHOWN) {
- SDL_HideWindow(m_sdl_window);
- }
- iret = 0;
- }
- return iret;
- }
- int VideoRenderImpl::StopVideoRender()
- {
- HideVideoWindow();
-
- m_refresh_flag = false;
- if (NULL != m_refresh_thread){
- SDL_WaitThread(m_refresh_thread, NULL);
- m_refresh_thread = NULL;
- }
-
- return 0;
- }
- void VideoRenderImpl::VideoRenderDestroy()
- {
- delete this;
- }
- int VideoRenderImpl::RenderVideoFrame(video_frame* pframe, RVC_RendererFlip eFlipType)
- {
- int iret = -1;
- if (NULL == m_sdl_window || NULL == pframe || NULL == m_renderer || NULL == m_rending_texture){
- return iret;
- }
- SDL_Event event;
- SDL_WaitEvent(&event);
- if(REFRESH_EVENT == event.type){
- 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 || VIDEO_FORMAT_I420 == pframe->format){
- if (VIDEO_FORMAT_RGB24 == pframe->format){
- SDL_UpdateTexture(m_rending_texture, NULL, pframe->data[0], pframe->width*3);
- }
- else{
- SDL_UpdateTexture(m_rending_texture, NULL, pframe->data[0], pframe->width);
- }
-
- if (RVC_FLIP_NONE == eFlipType){
- SDL_RenderCopy(m_renderer, m_rending_texture, NULL, NULL);
- }
- else{
- SDL_Point point = {m_videowidth/2, m_videoheight/2};
- SDL_RenderCopyEx(m_renderer, m_rending_texture, NULL, NULL, 0, &point, (SDL_RendererFlip)eFlipType);
- }
- }
- else{
- RenderLog(RENDER_LOG_ERROR, "%s:%d not support format, return", __FUNCTION__, __LINE__);
- return iret;
- }
- SDL_RenderPresent(m_renderer);
- }
- iret = 0;
- return iret;
- }
- void VideoRenderImpl::RenderLog(render_loglevel elevel, const char* fmt, ...)
- {
- if (m_callback.debug) {
- va_list arg;
- va_start(arg, fmt);
- if (*m_callback.debug){
- (*m_callback.debug)(elevel, m_callback.user_data, fmt, arg);
- }
- va_end(arg);
- }
- }
|