#include #include #include #include #include #include #include "CPicturePlayer.h" #ifndef SAFE_DELETE #define SAFE_DELETE(p) \ do{\ if(p) { \ delete p; \ p = NULL; \ } \ } while (0) #endif #ifndef SAFE_DELETE_ARRAY #define SAFE_DELETE_ARRAY(p) \ do{ \ if(p) { \ delete[] (p); \ (p)=NULL; \ }\ }while(0) #endif static char* rvc_strdup(const char* strdata) { char* strbuffer = NULL; if (NULL == strdata) { return strbuffer; } uint8_t ulen = strlen(strdata); if (strbuffer = (char*)malloc(ulen + 1)) { memset(strbuffer, 0, ulen + 1); memcpy(strbuffer, strdata, ulen); } return strbuffer; } static void rvc_strfree(char* strdata) { if (NULL != strdata) { free(strdata); strdata = NULL; } } #ifdef _WIN32 static char* GB2312ToUtf8(const char* gb2312) { int len = MultiByteToWideChar(CP_ACP, 0, gb2312, -1, NULL, 0); wchar_t* wstr = new wchar_t[len+1]; memset(wstr, 0, len+1); MultiByteToWideChar(CP_ACP, 0, gb2312, -1, wstr, len); len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL); char* str = new char[len+1]; memset(str, 0, len+1); WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL); if(wstr) delete[] wstr; return str; } #endif CPicturePlayer::CPicturePlayer(CPicHostApi* pHostApi) { m_thid = NULL; m_bplaying = false; m_window = NULL; m_nfile_cnt = 0; m_nplay_cnt = 0; m_nplay_interval = 5000; m_stricopath = NULL; memset(m_strroot_path, 0, MAX_PATH); for (size_t i = 0; i < MAX_FILECOUNT; i++){ memset(m_strfile_names[i], 0, MAX_PATH); } m_pHostApi = pHostApi; if (NULL != m_pHostApi){ char strIcoPath[MAX_PATH] = { 0 }; if (0 == pHostApi->GetPicPlayerIcoPath(strIcoPath, MAX_PATH)) { m_stricopath = rvc_strdup(strIcoPath); } } else { m_pHostApi->PicDebug(PIC_LOG_ERROR,"new CPicturePlayer failed!"); } for (int inum = 0; inum < MAX_DISPLAYNUM; inum++){ memset(&m_dispalymode[inum], 0, sizeof(SDL_DisplayMode)); } m_show_width = 0; m_show_height = 0; m_busrstop = false; Uint32 uRet = SDL_WasInit(SDL_INIT_VIDEO); if (0 == uRet) { if (SDL_Init(SDL_INIT_VIDEO)) { m_pHostApi->PicDebug(PIC_LOG_ERROR, "Could not initialize SDL - %s", SDL_GetError()); m_pHostApi->PicDebug(PIC_LOG_ERROR, "(Did you set the DISPLAY variable?)"); } else { uRet = SDL_WasInit(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER); m_pHostApi->PicDebug(PIC_LOG_DEBUG, "initialize SDL success, and init ret = %d.", uRet); } } } CPicturePlayer::~CPicturePlayer() { DeInit(); } size_t CPicturePlayer::GetVideoDisplayInfo() { size_t uCount = SDL_GetNumVideoDisplays(); m_pHostApi->PicDebug(PIC_LOG_DEBUG,"VideoDisplays Number is %d.", uCount); for (size_t i = 0; i < uCount && i < MAX_DISPLAYNUM; i++){ SDL_GetDesktopDisplayMode(i, &m_dispalymode[i]); m_pHostApi->PicDebug(PIC_LOG_DEBUG,"VideoDisplays{%d} format = %d", i, m_dispalymode[i].format); m_pHostApi->PicDebug(PIC_LOG_DEBUG,"VideoDisplays{%d} w = %d", i, m_dispalymode[i].w); m_pHostApi->PicDebug(PIC_LOG_DEBUG,"VideoDisplays{%d} h = %d", i, m_dispalymode[i].h); m_pHostApi->PicDebug(PIC_LOG_DEBUG,"VideoDisplays{%d} refresh_rate = %d", i, m_dispalymode[i].refresh_rate); } return uCount; } int CPicturePlayer::InitParam(rvc_picture_player_param_t* tparam) { int iRet = -1; if (NULL == tparam) { return iRet; } //if (0 != SDL_Init(SDL_INIT_VIDEO)) { // m_pHostApi->PicDebug(PIC_LOG_ERROR,"Could not initialize SDL - %s", SDL_GetError()); // m_pHostApi->PicDebug(PIC_LOG_ERROR, "(Did you set the DISPLAY variable?)"); // return iRet; //} #ifdef _WIN32 m_play_exit_event = CreateEventA(NULL, FALSE, FALSE, NULL); #else sem_init(&m_play_exit_sem, 0, 0); #endif m_busrstop = false; m_nfile_cnt = tparam->nfile_cnt; m_nplay_cnt = tparam->nplay_cnt; m_nplay_interval = tparam->nplay_interval; #ifdef _WIN32 _snprintf(m_strroot_path, MAX_PATH, "%s", tparam->strroot_path); for (size_t index = 0; index < m_nfile_cnt; index++) { _snprintf(m_strfile_names[index], MAX_PATH, "%s", tparam->strfile_names[index]); } m_uflag = SDL_WINDOW_BORDERLESS | SDL_WINDOW_OPENGL | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_SKIP_TASKBAR | SDL_WINDOW_POPUP_MENU; #else snprintf(m_strroot_path, MAX_PATH, "%s", tparam->strroot_path); for (size_t index = 0; index < m_nfile_cnt; index++) { snprintf(m_strfile_names[index], MAX_PATH, "%s", tparam->strfile_names[index]); } m_uflag = SDL_WINDOW_SHOWN|SDL_WINDOW_BORDERLESS|SDL_WINDOW_ALWAYS_ON_TOP|SDL_WINDOW_POPUP_MENU; if (tparam->bfull_screen) { m_uflag += SDL_WINDOW_FULLSCREEN; } #endif size_t uVideoPlayNum = GetVideoDisplayInfo(); m_idispalycx = 0; m_idispalycy = 0; int idispaly_width = m_dispalymode[0].w; int idispaly_height = m_dispalymode[0].h; if (false == tparam->bprim_monitor && uVideoPlayNum > 1) { m_idispalycx = m_dispalymode[0].w; idispaly_width = m_dispalymode[1].w; idispaly_height = m_dispalymode[1].h; } m_show_width = idispaly_width; m_show_height = idispaly_height; //2.设置播放器ico //if (NULL != m_stricopath) { // SDL_Surface* IconSurface = SDL_LoadBMP(m_stricopath); // if (NULL == IconSurface) { // m_pHostApi->PicDebug(PIC_LOG_ERROR, "SDL_LoadBMP(%s) failed: %s", m_stricopath, SDL_GetError()); // } // else { // SDL_SetWindowIcon(m_window, IconSurface); // SDL_FreeSurface(IconSurface); // } //} iRet = 0; return iRet; } int CPicturePlayer::DeInit() { int iRet = -1; rvc_strfree(m_stricopath); m_stricopath = NULL; m_show_width = 0; m_show_height = 0; m_busrstop = false; #ifdef _WIN32 if (NULL != m_play_exit_event){ CloseHandle(m_play_exit_event); m_play_exit_event = NULL; } #else sem_destroy(&m_play_exit_sem); #endif if (NULL != m_window) { SDL_DestroyWindow(m_window); } SDL_Quit(); iRet = 0; return iRet; } bool CPicturePlayer::StartPicPlay() { bool bRet = false; //1.创建播放窗体 m_window = SDL_CreateWindow("picture player", m_idispalycx, m_idispalycy, m_show_width, m_show_height, m_uflag ); if (NULL == m_window) { m_pHostApi->PicDebug(PIC_LOG_ERROR, "SDL_CreateWindow() failed: %s.", SDL_GetError()); return false; } else { int cx = 0, cy = 0; SDL_GetWindowPosition(m_window, &cx, &cy); m_pHostApi->PicDebug(PIC_LOG_DEBUG, "window flag is 0x%08x, cx = %d, cy = %d.", SDL_GetWindowFlags(m_window), cx, cy); } m_bplaying = true; m_pHostApi->PicDebug(PIC_LOG_DEBUG, "set m_bplaying = true"); #ifdef _WIN32 SDL_SysWMinfo info; HWND hwnd; SDL_VERSION(&info.version); if (SDL_GetWindowWMInfo(m_window, &info)) { hwnd = info.info.win.window; m_pHostApi->PicDebug(PIC_LOG_DEBUG, "SDL_GetWindowWMInfo success."); SetWindowPos(hwnd, HWND_TOPMOST, m_idispalycx, m_idispalycy, m_show_width, m_show_height, SWP_NOMOVE | SWP_NOSIZE); } else { m_pHostApi->PicDebug(PIC_LOG_DEBUG, "SDL_GetWindowWMInfo failed."); } #endif // _WIN32 SDL_Surface* surface = SDL_GetWindowSurface(m_window); int iPlayCount = 0; for (; iPlayCount < m_nplay_cnt; iPlayCount++) { if (m_busrstop) { break; } int index = 0; for (; index < m_nfile_cnt; index++) { if (m_busrstop) { break; } SDL_Surface* image = NULL; #ifdef _WIN32 char* strfilename = GB2312ToUtf8(m_strfile_names[index]); image = IMG_Load(strfilename); SAFE_DELETE_ARRAY(strfilename); #else image = IMG_Load(m_strfile_names[index]); #endif if (NULL == image) { m_pHostApi->PicDebug(PIC_LOG_ERROR, "IMG_Load %s failed!", m_strfile_names[index]); #ifdef _WIN32 strfilename = GB2312ToUtf8(m_strfile_names[index]); image = SDL_LoadBMP(strfilename); SAFE_DELETE_ARRAY(strfilename); #else image = SDL_LoadBMP(m_strfile_names[index]); #endif if (NULL == image) { continue; } } else { m_pHostApi->PicDebug(PIC_LOG_DEBUG, "IMG_Load %s success!", m_strfile_names[index]); } SDL_Rect dst; dst.x = 0; dst.y = 0; dst.w = m_show_width; dst.h = m_show_height; int itimes = m_nplay_interval; SDL_BlitSurface(image, NULL, surface, &dst); #ifdef _WIN32 DWORD t1 = 0,t2 = 0; t1 = GetTickCount(); while(itimes > 0){ DWORD dwRet = WaitForSingleObject(m_play_exit_event, 10); if (dwRet == WAIT_TIMEOUT){ SDL_Event event; while(SDL_PollEvent(&event)){ switch(event.type){ case SDL_QUIT: break; } } SDL_UpdateWindowSurface(m_window); itimes--; t2 = GetTickCount(); if (t2 - t1 > m_nplay_interval){ m_pHostApi->PicDebug(PIC_LOG_DEBUG, "%s:%d it's time to leave and itimems is %d.", __FUNCTION__, __LINE__, itimes); break; } } else { m_pHostApi->PicDebug(PIC_LOG_DEBUG, "%s:%d break circle.", __FUNCTION__, __LINE__); SDL_Delay(200); break; } } #else SDL_UpdateWindowSurface(m_window); struct timespec ts; m_pHostApi->PicDebug(PIC_LOG_DEBUG, "%s:%d itimes = %d.", __FUNCTION__, __LINE__, itimes); clock_gettime(CLOCK_REALTIME, &ts); if (itimes > 1000){ ts.tv_sec += (itimes / 1000); itimes = m_nplay_interval % 1000; } long unsec = ts.tv_nsec + (1000 * 1000 * itimes); ts.tv_sec += (unsec / 1000000000); ts.tv_nsec = (unsec % 1000000000); if (-1 == sem_timedwait(&m_play_exit_sem, &ts)) { if (ETIMEDOUT == errno) { } } else { m_pHostApi->PicDebug(PIC_LOG_DEBUG, "%s:%d break circle.", __FUNCTION__, __LINE__); SDL_Delay(200); break; } #endif SDL_FreeSurface(surface); SDL_FreeSurface(image); } } if (iPlayCount == m_nplay_cnt) { m_pHostApi->PicDebug(PIC_LOG_DEBUG, "%d times picture playing task finished, exit.", iPlayCount); } else{ m_pHostApi->PicDebug(PIC_LOG_DEBUG, "user stop picture playing task, exit."); } SDL_HideWindow(m_window); SDL_DestroyWindow(m_window); m_window = NULL; bRet = true; return bRet; } int CPicturePlayer::StopPicPlay() { int iRet = -1; #ifdef _WIN32 SetEvent(m_play_exit_event); #else sem_post(&m_play_exit_sem); #endif m_busrstop = true; m_pHostApi->PicDebug(PIC_LOG_DEBUG, "stop picture play, set user stop flag true."); iRet = 0; return iRet; } bool CPicturePlayer::GetPicPlayingFlag() { m_pHostApi->PicDebug(PIC_LOG_DEBUG, "m_bplaying flag is %s", m_bplaying ? "true" : "false"); return m_bplaying; } bool CPicturePlayer::SetPicPlayingFlag(bool bret) { m_bplaying = bret; m_pHostApi->PicDebug(PIC_LOG_DEBUG, "after set m_bplaying flag is %s", m_bplaying ? "true" : "false"); return true; }