CPicturePlayer.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. #include <stdio.h>
  2. #include <stdbool.h>
  3. #include <assert.h>
  4. #include <string.h>
  5. #include <time.h>
  6. #include <errno.h>
  7. #include "CPicturePlayer.h"
  8. #ifndef SAFE_DELETE
  9. #define SAFE_DELETE(p) \
  10. do{\
  11. if(p) { \
  12. delete p; \
  13. p = NULL; \
  14. } \
  15. } while (0)
  16. #endif
  17. #ifndef SAFE_DELETE_ARRAY
  18. #define SAFE_DELETE_ARRAY(p) \
  19. do{ \
  20. if(p) { \
  21. delete[] (p); \
  22. (p)=NULL; \
  23. }\
  24. }while(0)
  25. #endif
  26. static char* rvc_strdup(const char* strdata)
  27. {
  28. char* strbuffer = NULL;
  29. if (NULL == strdata)
  30. {
  31. return strbuffer;
  32. }
  33. uint8_t ulen = strlen(strdata);
  34. if (strbuffer = (char*)malloc(ulen + 1))
  35. {
  36. memset(strbuffer, 0, ulen + 1);
  37. memcpy(strbuffer, strdata, ulen);
  38. }
  39. return strbuffer;
  40. }
  41. static void rvc_strfree(char* strdata)
  42. {
  43. if (NULL != strdata)
  44. {
  45. free(strdata);
  46. strdata = NULL;
  47. }
  48. }
  49. #ifdef _WIN32
  50. static char* GB2312ToUtf8(const char* gb2312)
  51. {
  52. int len = MultiByteToWideChar(CP_ACP, 0, gb2312, -1, NULL, 0);
  53. wchar_t* wstr = new wchar_t[len+1];
  54. memset(wstr, 0, len+1);
  55. MultiByteToWideChar(CP_ACP, 0, gb2312, -1, wstr, len);
  56. len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
  57. char* str = new char[len+1];
  58. memset(str, 0, len+1);
  59. WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);
  60. if(wstr) delete[] wstr;
  61. return str;
  62. }
  63. #endif
  64. CPicturePlayer::CPicturePlayer(CPicHostApi* pHostApi)
  65. {
  66. m_thid = NULL;
  67. m_bplaying = false;
  68. m_window = NULL;
  69. m_nfile_cnt = 0;
  70. m_nplay_cnt = 0;
  71. m_nplay_interval = 5000;
  72. m_stricopath = NULL;
  73. memset(m_strroot_path, 0, MAX_PATH);
  74. for (size_t i = 0; i < MAX_FILECOUNT; i++){
  75. memset(m_strfile_names[i], 0, MAX_PATH);
  76. }
  77. m_pHostApi = pHostApi;
  78. if (NULL != m_pHostApi){
  79. char strIcoPath[MAX_PATH] = { 0 };
  80. if (0 == pHostApi->GetPicPlayerIcoPath(strIcoPath, MAX_PATH)) {
  81. m_stricopath = rvc_strdup(strIcoPath);
  82. }
  83. }
  84. else
  85. {
  86. m_pHostApi->PicDebug(PIC_LOG_ERROR,"new CPicturePlayer failed!");
  87. }
  88. for (int inum = 0; inum < MAX_DISPLAYNUM; inum++){
  89. memset(&m_dispalymode[inum], 0, sizeof(SDL_DisplayMode));
  90. }
  91. m_show_width = 0;
  92. m_show_height = 0;
  93. m_busrstop = false;
  94. Uint32 uRet = SDL_WasInit(SDL_INIT_VIDEO);
  95. if (0 == uRet) {
  96. if (SDL_Init(SDL_INIT_VIDEO))
  97. {
  98. m_pHostApi->PicDebug(PIC_LOG_ERROR, "Could not initialize SDL - %s", SDL_GetError());
  99. m_pHostApi->PicDebug(PIC_LOG_ERROR, "(Did you set the DISPLAY variable?)");
  100. }
  101. else {
  102. uRet = SDL_WasInit(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER);
  103. m_pHostApi->PicDebug(PIC_LOG_DEBUG, "initialize SDL success, and init ret = %d.", uRet);
  104. }
  105. }
  106. }
  107. CPicturePlayer::~CPicturePlayer()
  108. {
  109. DeInit();
  110. }
  111. size_t CPicturePlayer::GetVideoDisplayInfo()
  112. {
  113. size_t uCount = SDL_GetNumVideoDisplays();
  114. m_pHostApi->PicDebug(PIC_LOG_DEBUG,"VideoDisplays Number is %d.", uCount);
  115. for (size_t i = 0; i < uCount && i < MAX_DISPLAYNUM; i++){
  116. SDL_GetDesktopDisplayMode(i, &m_dispalymode[i]);
  117. m_pHostApi->PicDebug(PIC_LOG_DEBUG,"VideoDisplays{%d} format = %d", i, m_dispalymode[i].format);
  118. m_pHostApi->PicDebug(PIC_LOG_DEBUG,"VideoDisplays{%d} w = %d", i, m_dispalymode[i].w);
  119. m_pHostApi->PicDebug(PIC_LOG_DEBUG,"VideoDisplays{%d} h = %d", i, m_dispalymode[i].h);
  120. m_pHostApi->PicDebug(PIC_LOG_DEBUG,"VideoDisplays{%d} refresh_rate = %d", i, m_dispalymode[i].refresh_rate);
  121. }
  122. return uCount;
  123. }
  124. int CPicturePlayer::InitParam(rvc_picture_player_param_t* tparam)
  125. {
  126. int iRet = -1;
  127. if (NULL == tparam) {
  128. return iRet;
  129. }
  130. //if (0 != SDL_Init(SDL_INIT_VIDEO)) {
  131. // m_pHostApi->PicDebug(PIC_LOG_ERROR,"Could not initialize SDL - %s", SDL_GetError());
  132. // m_pHostApi->PicDebug(PIC_LOG_ERROR, "(Did you set the DISPLAY variable?)");
  133. // return iRet;
  134. //}
  135. #ifdef _WIN32
  136. m_play_exit_event = CreateEventA(NULL, FALSE, FALSE, NULL);
  137. #else
  138. sem_init(&m_play_exit_sem, 0, 0);
  139. #endif
  140. m_busrstop = false;
  141. m_nfile_cnt = tparam->nfile_cnt;
  142. m_nplay_cnt = tparam->nplay_cnt;
  143. m_nplay_interval = tparam->nplay_interval;
  144. #ifdef _WIN32
  145. _snprintf(m_strroot_path, MAX_PATH, "%s", tparam->strroot_path);
  146. for (size_t index = 0; index < m_nfile_cnt; index++) {
  147. _snprintf(m_strfile_names[index], MAX_PATH, "%s", tparam->strfile_names[index]);
  148. }
  149. m_uflag = SDL_WINDOW_BORDERLESS | SDL_WINDOW_OPENGL | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_SKIP_TASKBAR | SDL_WINDOW_POPUP_MENU;
  150. #else
  151. snprintf(m_strroot_path, MAX_PATH, "%s", tparam->strroot_path);
  152. for (size_t index = 0; index < m_nfile_cnt; index++) {
  153. snprintf(m_strfile_names[index], MAX_PATH, "%s", tparam->strfile_names[index]);
  154. }
  155. m_uflag = SDL_WINDOW_SHOWN|SDL_WINDOW_BORDERLESS|SDL_WINDOW_ALWAYS_ON_TOP|SDL_WINDOW_POPUP_MENU;
  156. if (tparam->bfull_screen) {
  157. m_uflag += SDL_WINDOW_FULLSCREEN;
  158. }
  159. #endif
  160. size_t uVideoPlayNum = GetVideoDisplayInfo();
  161. m_idispalycx = 0;
  162. m_idispalycy = 0;
  163. int idispaly_width = m_dispalymode[0].w;
  164. int idispaly_height = m_dispalymode[0].h;
  165. if (false == tparam->bprim_monitor && uVideoPlayNum > 1) {
  166. m_idispalycx = m_dispalymode[0].w;
  167. idispaly_width = m_dispalymode[1].w;
  168. idispaly_height = m_dispalymode[1].h;
  169. }
  170. m_show_width = idispaly_width;
  171. m_show_height = idispaly_height;
  172. //2.设置播放器ico
  173. //if (NULL != m_stricopath) {
  174. // SDL_Surface* IconSurface = SDL_LoadBMP(m_stricopath);
  175. // if (NULL == IconSurface) {
  176. // m_pHostApi->PicDebug(PIC_LOG_ERROR, "SDL_LoadBMP(%s) failed: %s", m_stricopath, SDL_GetError());
  177. // }
  178. // else {
  179. // SDL_SetWindowIcon(m_window, IconSurface);
  180. // SDL_FreeSurface(IconSurface);
  181. // }
  182. //}
  183. iRet = 0;
  184. return iRet;
  185. }
  186. int CPicturePlayer::DeInit()
  187. {
  188. int iRet = -1;
  189. rvc_strfree(m_stricopath);
  190. m_stricopath = NULL;
  191. m_show_width = 0;
  192. m_show_height = 0;
  193. m_busrstop = false;
  194. #ifdef _WIN32
  195. if (NULL != m_play_exit_event){
  196. CloseHandle(m_play_exit_event);
  197. m_play_exit_event = NULL;
  198. }
  199. #else
  200. sem_destroy(&m_play_exit_sem);
  201. #endif
  202. if (NULL != m_window) {
  203. SDL_DestroyWindow(m_window);
  204. }
  205. SDL_Quit();
  206. iRet = 0;
  207. return iRet;
  208. }
  209. bool CPicturePlayer::StartPicPlay()
  210. {
  211. bool bRet = false;
  212. //1.创建播放窗体
  213. m_window = SDL_CreateWindow("picture player",
  214. m_idispalycx,
  215. m_idispalycy,
  216. m_show_width,
  217. m_show_height,
  218. m_uflag
  219. );
  220. if (NULL == m_window) {
  221. m_pHostApi->PicDebug(PIC_LOG_ERROR, "SDL_CreateWindow() failed: %s.", SDL_GetError());
  222. return false;
  223. }
  224. else {
  225. int cx = 0, cy = 0;
  226. SDL_GetWindowPosition(m_window, &cx, &cy);
  227. m_pHostApi->PicDebug(PIC_LOG_DEBUG, "window flag is 0x%08x, cx = %d, cy = %d.", SDL_GetWindowFlags(m_window), cx, cy);
  228. }
  229. m_bplaying = true;
  230. m_pHostApi->PicDebug(PIC_LOG_DEBUG, "set m_bplaying = true");
  231. #ifdef _WIN32
  232. SDL_SysWMinfo info;
  233. HWND hwnd;
  234. SDL_VERSION(&info.version);
  235. if (SDL_GetWindowWMInfo(m_window, &info)) {
  236. hwnd = info.info.win.window;
  237. m_pHostApi->PicDebug(PIC_LOG_DEBUG, "SDL_GetWindowWMInfo success.");
  238. SetWindowPos(hwnd,
  239. HWND_TOPMOST,
  240. m_idispalycx,
  241. m_idispalycy,
  242. m_show_width,
  243. m_show_height,
  244. SWP_NOMOVE | SWP_NOSIZE);
  245. }
  246. else {
  247. m_pHostApi->PicDebug(PIC_LOG_DEBUG, "SDL_GetWindowWMInfo failed.");
  248. }
  249. #endif // _WIN32
  250. SDL_Surface* surface = SDL_GetWindowSurface(m_window);
  251. int iPlayCount = 0;
  252. for (; iPlayCount < m_nplay_cnt; iPlayCount++)
  253. {
  254. if (m_busrstop) {
  255. break;
  256. }
  257. int index = 0;
  258. for (; index < m_nfile_cnt; index++)
  259. {
  260. if (m_busrstop) {
  261. break;
  262. }
  263. SDL_Surface* image = NULL;
  264. #ifdef _WIN32
  265. char* strfilename = GB2312ToUtf8(m_strfile_names[index]);
  266. image = IMG_Load(strfilename);
  267. SAFE_DELETE_ARRAY(strfilename);
  268. #else
  269. image = IMG_Load(m_strfile_names[index]);
  270. #endif
  271. if (NULL == image) {
  272. m_pHostApi->PicDebug(PIC_LOG_ERROR, "IMG_Load %s failed!", m_strfile_names[index]);
  273. #ifdef _WIN32
  274. strfilename = GB2312ToUtf8(m_strfile_names[index]);
  275. image = SDL_LoadBMP(strfilename);
  276. SAFE_DELETE_ARRAY(strfilename);
  277. #else
  278. image = SDL_LoadBMP(m_strfile_names[index]);
  279. #endif
  280. if (NULL == image) {
  281. continue;
  282. }
  283. }
  284. else {
  285. m_pHostApi->PicDebug(PIC_LOG_DEBUG, "IMG_Load %s success!", m_strfile_names[index]);
  286. }
  287. SDL_Rect dst;
  288. dst.x = 0;
  289. dst.y = 0;
  290. dst.w = m_show_width;
  291. dst.h = m_show_height;
  292. int itimes = m_nplay_interval;
  293. SDL_BlitSurface(image, NULL, surface, &dst);
  294. #ifdef _WIN32
  295. DWORD t1 = 0,t2 = 0;
  296. t1 = GetTickCount();
  297. while(itimes > 0){
  298. DWORD dwRet = WaitForSingleObject(m_play_exit_event, 10);
  299. if (dwRet == WAIT_TIMEOUT){
  300. SDL_Event event;
  301. while(SDL_PollEvent(&event)){
  302. switch(event.type){
  303. case SDL_QUIT:
  304. break;
  305. }
  306. }
  307. SDL_UpdateWindowSurface(m_window);
  308. itimes--;
  309. t2 = GetTickCount();
  310. if (t2 - t1 > m_nplay_interval){
  311. m_pHostApi->PicDebug(PIC_LOG_DEBUG, "%s:%d it's time to leave and itimems is %d.", __FUNCTION__, __LINE__, itimes);
  312. break;
  313. }
  314. }
  315. else {
  316. m_pHostApi->PicDebug(PIC_LOG_DEBUG, "%s:%d break circle.", __FUNCTION__, __LINE__);
  317. SDL_Delay(200);
  318. break;
  319. }
  320. }
  321. #else
  322. SDL_UpdateWindowSurface(m_window);
  323. struct timespec ts;
  324. m_pHostApi->PicDebug(PIC_LOG_DEBUG, "%s:%d itimes = %d.", __FUNCTION__, __LINE__, itimes);
  325. clock_gettime(CLOCK_REALTIME, &ts);
  326. if (itimes > 1000){
  327. ts.tv_sec += (itimes / 1000);
  328. itimes = m_nplay_interval % 1000;
  329. }
  330. long unsec = ts.tv_nsec + (1000 * 1000 * itimes);
  331. ts.tv_sec += (unsec / 1000000000);
  332. ts.tv_nsec = (unsec % 1000000000);
  333. if (-1 == sem_timedwait(&m_play_exit_sem, &ts)) {
  334. if (ETIMEDOUT == errno) {
  335. }
  336. }
  337. else {
  338. m_pHostApi->PicDebug(PIC_LOG_DEBUG, "%s:%d break circle.", __FUNCTION__, __LINE__);
  339. SDL_Delay(200);
  340. break;
  341. }
  342. #endif
  343. SDL_FreeSurface(surface);
  344. SDL_FreeSurface(image);
  345. }
  346. }
  347. if (iPlayCount == m_nplay_cnt) {
  348. m_pHostApi->PicDebug(PIC_LOG_DEBUG, "%d times picture playing task finished, exit.", iPlayCount);
  349. }
  350. else{
  351. m_pHostApi->PicDebug(PIC_LOG_DEBUG, "user stop picture playing task, exit.");
  352. }
  353. SDL_HideWindow(m_window);
  354. SDL_DestroyWindow(m_window);
  355. m_window = NULL;
  356. bRet = true;
  357. return bRet;
  358. }
  359. int CPicturePlayer::StopPicPlay()
  360. {
  361. int iRet = -1;
  362. #ifdef _WIN32
  363. SetEvent(m_play_exit_event);
  364. #else
  365. sem_post(&m_play_exit_sem);
  366. #endif
  367. m_busrstop = true;
  368. m_pHostApi->PicDebug(PIC_LOG_DEBUG, "stop picture play, set user stop flag true.");
  369. iRet = 0;
  370. return iRet;
  371. }
  372. bool CPicturePlayer::GetPicPlayingFlag()
  373. {
  374. m_pHostApi->PicDebug(PIC_LOG_DEBUG, "m_bplaying flag is %s", m_bplaying ? "true" : "false");
  375. return m_bplaying;
  376. }
  377. bool CPicturePlayer::SetPicPlayingFlag(bool bret)
  378. {
  379. m_bplaying = bret;
  380. m_pHostApi->PicDebug(PIC_LOG_DEBUG, "after set m_bplaying flag is %s", m_bplaying ? "true" : "false");
  381. return true;
  382. }