player.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716
  1. #include <stdio.h>
  2. #include <stdbool.h>
  3. #include <assert.h>
  4. #include "player.h"
  5. #include "frame.h"
  6. #include "packet.h"
  7. #include "demux.h"
  8. #include "video.h"
  9. #include "audio.h"
  10. static int initialized = 0;
  11. // 返回值:返回上一帧的pts更新值(上一帧pts+流逝的时间)
  12. double get_clock(play_clock_t *c)
  13. {
  14. if (*c->queue_serial != c->serial)
  15. {
  16. return NAN;
  17. }
  18. if (c->paused)
  19. {
  20. return c->pts;
  21. }
  22. else
  23. {
  24. double time = av_gettime_relative() / 1000000.0;
  25. double ret = c->pts_drift + time; // 展开得: c->pts + (time - c->last_updated)
  26. return ret;
  27. }
  28. }
  29. void set_clock_at(play_clock_t *c, double pts, int serial, double time)
  30. {
  31. c->pts = pts;
  32. c->last_updated = time;
  33. c->pts_drift = c->pts - time;
  34. c->serial = serial;
  35. }
  36. void set_clock(play_clock_t *c, double pts, int serial)
  37. {
  38. double time = av_gettime_relative() / 1000000.0;
  39. set_clock_at(c, pts, serial, time);
  40. }
  41. static void set_clock_speed(play_clock_t *c, double speed)
  42. {
  43. set_clock(c, get_clock(c), c->serial);
  44. c->speed = speed;
  45. }
  46. void init_clock(play_clock_t *c, int *queue_serial)
  47. {
  48. c->speed = 1.0;
  49. c->paused = 0;
  50. c->queue_serial = queue_serial;
  51. set_clock(c, NAN, -1);
  52. }
  53. static void sync_play_clock_to_slave(play_clock_t *c, play_clock_t *slave)
  54. {
  55. double clock = get_clock(c);
  56. double slave_clock = get_clock(slave);
  57. if (!isnan(slave_clock) && (isnan(clock) || fabs(clock - slave_clock) > AV_NOSYNC_THRESHOLD))
  58. set_clock(c, slave_clock, slave->serial);
  59. }
  60. /* pause or resume the video */
  61. static void stream_toggle_pause(player_stat_t *is)
  62. {
  63. if (is->m_ipaused)
  64. {
  65. // 这里表示当前是暂停状态,将切换到继续播放状态。在继续播放之前,先将暂停期间流逝的时间加到frame_timer中
  66. is->frame_timer += av_gettime_relative() / 1000000.0 - is->video_clk.last_updated;
  67. set_clock(&is->video_clk, get_clock(&is->video_clk), is->video_clk.serial);
  68. }
  69. is->m_ipaused = is->audio_clk.paused = is->video_clk.paused = !is->m_ipaused;
  70. }
  71. static void toggle_pause(player_stat_t *is)
  72. {
  73. stream_toggle_pause(is);
  74. is->m_istep = 0;
  75. }
  76. static void toggle_full_screen(player_stat_t* is)
  77. {
  78. SDL_SetWindowFullscreen(is->sdl_video.window, SDL_WINDOW_FULLSCREEN_DESKTOP);
  79. }
  80. CMediaPlayer::CMediaPlayer(CMediaHostApi* pHostApi)
  81. {
  82. m_hostapi = pHostApi;
  83. m_player_stat = NULL;
  84. m_uvolume = SDL_MIX_MAXVOLUME/2;
  85. m_bplaying = false;
  86. m_piconpath = NULL;
  87. m_paudiodev = NULL;
  88. m_bmediaplay_started_flag = false;
  89. m_mediaplay_started_sem = NULL;
  90. m_bmediaplay_start_failed = false;
  91. m_meida_play_start_wait_mutex = SDL_CreateMutex();
  92. if (NULL != m_hostapi){
  93. char str_iconpath[MAX_PATH] = {0};
  94. if (0 == pHostApi->GetMediaPlayerIcoPath(str_iconpath, MAX_PATH)){
  95. m_piconpath = av_strdup(str_iconpath);
  96. }
  97. char str_audiodev[MAX_PATH] = { 0 };
  98. if (0 == pHostApi->GetAudioOutDevName(str_audiodev, MAX_PATH)) {
  99. m_paudiodev = av_strdup(str_audiodev);
  100. }
  101. else {
  102. m_paudiodev = NULL;
  103. }
  104. }
  105. else {
  106. m_hostapi->Debug(MEDIA_LOG_ERROR, "new CMediaPlayer failed!");
  107. }
  108. if (initialized){
  109. ++initialized;
  110. }
  111. else {
  112. if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)){
  113. m_hostapi->Debug(MEDIA_LOG_ERROR, "Could not initialize SDL - %s", SDL_GetError());
  114. m_hostapi->Debug(MEDIA_LOG_ERROR, "(Did you set the DISPLAY variable?)");
  115. }
  116. else {
  117. initialized++;
  118. }
  119. }
  120. }
  121. CMediaPlayer::~CMediaPlayer()
  122. {
  123. if (NULL != m_meida_play_start_wait_mutex) {
  124. SDL_DestroyMutex(m_meida_play_start_wait_mutex);
  125. m_meida_play_start_wait_mutex = NULL;
  126. }
  127. if (NULL != m_player_stat) {
  128. UnInitialize_Player_Stat();
  129. }
  130. if (NULL != m_piconpath) {
  131. av_free(m_piconpath);
  132. m_piconpath = NULL;
  133. }
  134. if (NULL != m_paudiodev){
  135. av_free(m_paudiodev);
  136. m_paudiodev = NULL;
  137. }
  138. if (--initialized == 0){
  139. SDL_Quit();
  140. }
  141. }
  142. static int audio_volume_callback(int* audiovolume, void* userdata)
  143. {
  144. CMediaPlayer* player = (CMediaPlayer*)userdata;
  145. *audiovolume = player->GetVolume();
  146. return 0;
  147. }
  148. static int audio_play_finished_callback(void* userdata)
  149. {
  150. CMediaPlayer* player = (CMediaPlayer*)userdata;
  151. if (NULL != player){
  152. player->SetFinishedFlag();
  153. }
  154. return 0;
  155. }
  156. static int mediaplay_thread_func(void* arg)
  157. {
  158. int iret = -1;
  159. int icount = 0;
  160. CMediaPlayer* pPlayer = (CMediaPlayer*)arg;
  161. if (0 != open_demux(pPlayer->GetPlayerStat())) {
  162. pPlayer->GetMediaHostApi()->Debug(MEDIA_LOG_ERROR, "open_demux function call failed.");
  163. return iret;
  164. }
  165. if (eVideo_Type == pPlayer->GetPlayerStat()->m_eMType) {
  166. iret = open_video(pPlayer->GetPlayerStat());
  167. if (0 != iret) {
  168. pPlayer->GetMediaHostApi()->Debug(MEDIA_LOG_ERROR, "open video failed.");
  169. pPlayer->StartMediaPlayFailed();
  170. return iret;
  171. }
  172. }
  173. iret = open_audio(pPlayer->GetPlayerStat());
  174. if (0 == iret) {
  175. bool baudioplay_thread_exit = false;
  176. do {
  177. if (NULL != pPlayer->GetPlayerStat()->m_audio_play_wait_sem) {
  178. int iWait = SDL_SemWaitTimeout(pPlayer->GetPlayerStat()->m_audio_play_wait_sem, 5);
  179. if (0 != iWait) {
  180. if (SDL_MUTEX_TIMEDOUT == iWait) {
  181. if (false == pPlayer->GetMediaPlayStartedFlag()) {
  182. pPlayer->SetMediaPlayStartedFlag(true);
  183. }
  184. }
  185. else {
  186. pPlayer->GetMediaHostApi()->Debug(MEDIA_LOG_ERROR, "SDL_SemWaitTimeout error.");
  187. }
  188. }
  189. else {
  190. baudioplay_thread_exit = true;
  191. }
  192. }
  193. else {
  194. pPlayer->GetMediaHostApi()->Debug(MEDIA_LOG_ERROR, "invalid m_audio_play_wait_sem");
  195. baudioplay_thread_exit = true;
  196. }
  197. } while (!baudioplay_thread_exit);
  198. SDL_CloseAudioDevice(pPlayer->GetPlayerStat()->m_audio_dev);
  199. }
  200. else {
  201. pPlayer->StartMediaPlayFailed();
  202. return iret;
  203. }
  204. return iret;
  205. }
  206. bool CMediaPlayer::SetFinishedFlag()
  207. {
  208. if (NULL != m_player_stat){
  209. if (NULL != m_hostapi) {
  210. m_hostapi->Debug(MEDIA_LOG_DEBUG, "%s:%d set baudio_finished to true.", __FUNCTION__, __LINE__);
  211. }
  212. }
  213. else {
  214. if (NULL != m_hostapi) {
  215. m_hostapi->Debug(MEDIA_LOG_INFO, "%s:%d m_player_stat is null and set audio finished flag failed.", __FUNCTION__, __LINE__);
  216. }
  217. }
  218. return true;
  219. }
  220. uint8_t CMediaPlayer::GetVolume()
  221. {
  222. return m_uvolume;
  223. }
  224. eMediaType_t CMediaPlayer::GetPlayingMediaType()
  225. {
  226. return m_player_stat->m_eMType;
  227. }
  228. player_stat_t* CMediaPlayer::GetPlayerStat()
  229. {
  230. return m_player_stat;
  231. }
  232. CMediaHostApi* CMediaPlayer::GetMediaHostApi()
  233. {
  234. return m_hostapi;
  235. }
  236. bool CMediaPlayer::GetMediaPlayStartedFlag()
  237. {
  238. return m_bmediaplay_started_flag;
  239. }
  240. void CMediaPlayer::SetMediaPlayStartedFlag(bool bflag)
  241. {
  242. m_bmediaplay_started_flag = bflag;
  243. }
  244. void CMediaPlayer::StartMediaPlayFailed()
  245. {
  246. m_bmediaplay_start_failed = true;
  247. }
  248. SDL_mutex* CMediaPlayer::GetMeidaPlayStartWaitMutex()
  249. {
  250. return m_meida_play_start_wait_mutex;
  251. }
  252. int CMediaPlayer::Initialize_Player_Stat(rvc_media_player_param_t* pMedia_Player)
  253. {
  254. int iRet = -1;
  255. if (NULL == pMedia_Player) {
  256. return iRet;
  257. }
  258. if (NULL != m_player_stat) {
  259. UnInitialize_Player_Stat();
  260. }
  261. m_player_stat = (player_stat_t*)av_mallocz(sizeof(player_stat_t));
  262. if (NULL == m_player_stat) {
  263. m_hostapi->Debug(MEDIA_LOG_ERROR, "player_stat_t struct malloc failed!");
  264. return iRet;
  265. }
  266. m_player_stat->buser_stop = false;
  267. m_player_stat->rvc_hostapi = m_hostapi;
  268. m_player_stat->m_prvc_cb = pMedia_Player->cb;
  269. m_player_stat->m_eMType = pMedia_Player->eType;
  270. m_player_stat->m_eWindType = pMedia_Player->m_eWindType;
  271. m_player_stat->bvice_monitor = pMedia_Player->bvicemonitor;
  272. m_player_stat->iDisplayCx = pMedia_Player->idisplaycx;
  273. m_player_stat->iDisplayCy = pMedia_Player->idisplaycy;
  274. m_player_stat->iDisplayWidth = pMedia_Player->idisplaywidth;
  275. m_player_stat->iDisplayHeight = pMedia_Player->idisplayheight;
  276. m_player_stat->on_audio_volume = &audio_volume_callback;
  277. m_player_stat->on_audio_play_finished = &audio_play_finished_callback;
  278. m_player_stat->user_data = this;
  279. if (NULL != m_piconpath){
  280. m_player_stat->m_piconpath = av_strdup(m_piconpath);
  281. }
  282. if (NULL != m_paudiodev){
  283. m_player_stat->m_paudiodev = av_strdup(m_paudiodev);
  284. }
  285. m_player_stat->uVolume = m_uvolume;
  286. m_player_stat->m_uFilesCount = pMedia_Player->m_uFilesCount;
  287. m_player_stat->m_icurrent_index = 0;
  288. m_player_stat->m_iaudio_dec_index = 0;
  289. for (size_t i = 0; i < pMedia_Player->m_uFilesCount; i++){
  290. memcpy(m_player_stat->m_strPlayLists[i], pMedia_Player->m_strPlayLists[i], strlen(pMedia_Player->m_strPlayLists[i]));
  291. }
  292. if (0 == pMedia_Player->m_uFilesCount || NULL == m_player_stat->rvc_hostapi || NULL == m_player_stat->m_prvc_cb || NULL == m_player_stat->m_piconpath) {
  293. UnInitialize_Player_Stat();
  294. return iRet;
  295. }
  296. else{
  297. iRet = 0;
  298. }
  299. return iRet;
  300. }
  301. int CMediaPlayer::UnInitialize_Player_Stat()
  302. {
  303. /* XXX: use a special url_shutdown call to abort parse cleanly */
  304. if (NULL == m_player_stat) {
  305. return -1;
  306. }
  307. for (int index = 0; index < m_player_stat->m_uFilesCount; index++) {
  308. if (NULL != m_player_stat->m_pfmt_ctx[index]) {
  309. avformat_close_input(&m_player_stat->m_pfmt_ctx[index]);
  310. avformat_free_context(m_player_stat->m_pfmt_ctx[index]);
  311. m_player_stat->m_pfmt_ctx[index] = NULL;
  312. }
  313. if (NULL != m_player_stat->m_pacodec_ctx[index]) {
  314. avcodec_close(m_player_stat->m_pacodec_ctx[index]);
  315. avcodec_free_context(&m_player_stat->m_pacodec_ctx[index]);
  316. }
  317. if (NULL != m_player_stat->m_pvcodec_ctx[index]) {
  318. avcodec_close(m_player_stat->m_pvcodec_ctx[index]);
  319. avcodec_free_context(&m_player_stat->m_pvcodec_ctx[index]);
  320. }
  321. }
  322. SDL_DestroyCond(m_player_stat->m_continue_read_thread);
  323. SDL_DestroySemaphore(m_player_stat->m_audio_play_wait_sem);
  324. m_player_stat->m_audio_play_wait_sem = NULL;
  325. if (m_player_stat->m_eMType == eVideo_Type) {
  326. for (int index = 0; index < m_player_stat->m_uFilesCount; index++) {
  327. if (NULL != m_player_stat->m_pimg_convert_ctx[index]) {
  328. sws_freeContext(m_player_stat->m_pimg_convert_ctx[index]);
  329. m_player_stat->m_pimg_convert_ctx[index] = NULL;
  330. }
  331. if (NULL != m_player_stat->m_pfrm_yuv[index]) {
  332. av_frame_free(&m_player_stat->m_pfrm_yuv[index]);
  333. av_frame_unref(m_player_stat->m_pfrm_yuv[index]);
  334. }
  335. if (NULL != m_player_stat->m_pvideo_buffer[index]) {
  336. av_free(m_player_stat->m_pvideo_buffer[index]);
  337. m_player_stat->m_pvideo_buffer[index] = NULL;
  338. }
  339. }
  340. }
  341. packet_queue_destroy(&m_player_stat->video_pkt_queue, m_hostapi);
  342. packet_queue_destroy(&m_player_stat->audio_pkt_queue, m_hostapi);
  343. ///* free all pictures */
  344. frame_queue_destory(&m_player_stat->video_frm_queue);
  345. frame_queue_destory(&m_player_stat->audio_frm_queue);
  346. swr_free(&m_player_stat->m_paudio_swr_ctx);
  347. //if (NULL != m_player_stat->m_paudio_frm) {
  348. // av_free(m_player_stat->m_paudio_frm);
  349. // m_player_stat->m_paudio_frm = NULL;
  350. //}
  351. if (NULL != m_player_stat->m_paudio_frm_rwr) {
  352. av_free(m_player_stat->m_paudio_frm_rwr);
  353. m_player_stat->m_paudio_frm_rwr = NULL;
  354. }
  355. if (m_player_stat->m_piconpath){
  356. av_free(m_player_stat->m_piconpath);
  357. m_player_stat->m_piconpath = NULL;
  358. }
  359. if (m_player_stat->m_paudiodev) {
  360. av_free(m_player_stat->m_paudiodev);
  361. m_player_stat->m_paudiodev = NULL;
  362. }
  363. if (m_player_stat->m_straudiodev) {
  364. av_free(m_player_stat->m_straudiodev);
  365. m_player_stat->m_straudiodev = NULL;
  366. }
  367. av_free(m_player_stat);
  368. m_player_stat = NULL;
  369. return 0;
  370. }
  371. int CMediaPlayer::GetViceVideoDisplayInfo(int* icx, int* icy, int* iwidth, int* iheight)
  372. {
  373. int iRet = -1;
  374. size_t uCount = SDL_GetNumVideoDisplays();
  375. //m_hostapi->Debug(MEDIA_LOG_DEBUG, "VideoDisplays Number is %d.", uCount);
  376. SDL_DisplayMode dispalymode[RVC_MAX_DISPLAYNUM] = { 0 };
  377. for (size_t i = 0; i < uCount && i < RVC_MAX_DISPLAYNUM; i++) {
  378. SDL_GetDesktopDisplayMode(i, &dispalymode[i]);
  379. //m_hostapi->Debug(MEDIA_LOG_DEBUG, "VideoDisplays{%d} format = %d", i, dispalymode[i].format);
  380. //m_hostapi->Debug(MEDIA_LOG_DEBUG, "VideoDisplays{%d} w = %d", i, dispalymode[i].w);
  381. //m_hostapi->Debug(MEDIA_LOG_DEBUG, "VideoDisplays{%d} h = %d", i, dispalymode[i].h);
  382. //m_hostapi->Debug(MEDIA_LOG_DEBUG, "VideoDisplays{%d} refresh_rate = %d", i, dispalymode[i].refresh_rate);
  383. }
  384. if (uCount > 1) {
  385. *icx = dispalymode[0].w;
  386. *icy = 0;
  387. *iwidth = dispalymode[1].w;
  388. *iheight = dispalymode[1].h;
  389. iRet = 0;
  390. }
  391. return iRet;
  392. }
  393. int CMediaPlayer::InitParam(rvc_media_player_param_t* pMedia_Player)
  394. {
  395. int iRet = -1;
  396. if (0 != Initialize_Player_Stat(pMedia_Player)){
  397. return iRet;
  398. }
  399. //m_hostapi->Debug(MEDIA_LOG_DEBUG, "initialize player stat success.");
  400. /* start video display */
  401. if (frame_queue_init(&m_player_stat->video_frm_queue, &m_player_stat->video_pkt_queue, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0 ||
  402. frame_queue_init(&m_player_stat->audio_frm_queue, &m_player_stat->audio_pkt_queue, SAMPLE_QUEUE_SIZE, 1) < 0)
  403. {
  404. m_hostapi->Debug(MEDIA_LOG_DEBUG, "media frame queue init failed!");
  405. UnInitialize_Player_Stat();
  406. return iRet;
  407. }
  408. /* init packet queue */
  409. if (packet_queue_init(&m_player_stat->video_pkt_queue, m_hostapi) < 0 ||
  410. packet_queue_init(&m_player_stat->audio_pkt_queue, m_hostapi) < 0)
  411. {
  412. m_hostapi->Debug(MEDIA_LOG_DEBUG, "media packet queue init failed!");
  413. UnInitialize_Player_Stat();
  414. return iRet;
  415. }
  416. /* put end pkt into packet queue */
  417. AVPacket flush_pkt = {0};
  418. flush_pkt.data = NULL;
  419. packet_queue_put(&m_player_stat->video_pkt_queue, &flush_pkt, m_hostapi);
  420. packet_queue_put(&m_player_stat->audio_pkt_queue, &flush_pkt, m_hostapi);
  421. if (!(m_player_stat->m_continue_read_thread = SDL_CreateCond())){
  422. m_hostapi->Debug(MEDIA_LOG_DEBUG, "SDL_CreateCond(): %s.", SDL_GetError());
  423. UnInitialize_Player_Stat();
  424. return iRet;
  425. }
  426. m_player_stat->m_audio_play_wait_sem = SDL_CreateSemaphore(0);
  427. init_clock(&m_player_stat->video_clk, &m_player_stat->video_pkt_queue.serial);
  428. init_clock(&m_player_stat->audio_clk, &m_player_stat->audio_pkt_queue.serial);
  429. if (m_player_stat->bvice_monitor){
  430. if (0 == GetViceVideoDisplayInfo(&m_player_stat->iDisplayCx, &m_player_stat->iDisplayCy, &m_player_stat->iDisplayWidth, &m_player_stat->iDisplayHeight)){
  431. }
  432. }
  433. iRet = 0;
  434. return iRet;
  435. }
  436. int CMediaPlayer::SetVolume(uint8_t uVolume)
  437. {
  438. int iRet = -1;
  439. m_uvolume = uVolume * SDL_MIX_MAXVOLUME/100;
  440. iRet = 0;
  441. return iRet;
  442. }
  443. bool CMediaPlayer::GetPlayingFlag()
  444. {
  445. return m_bplaying;
  446. }
  447. int CMediaPlayer::StartMediaPlay()
  448. {
  449. int iRet = -1;
  450. m_bplaying = true;
  451. SDL_LockMutex(m_meida_play_start_wait_mutex);
  452. m_bmediaplay_started_flag = false;
  453. m_bmediaplay_start_failed = false;
  454. m_mediaplay_started_sem = SDL_CreateSemaphore(0);
  455. m_mediaplay_tid = SDL_CreateThread(mediaplay_thread_func, "mediaplay_thread", this);
  456. if (NULL == m_mediaplay_tid) {
  457. SDL_UnlockMutex(m_meida_play_start_wait_mutex);
  458. m_hostapi->Debug(MEDIA_LOG_ERROR, "SDL_CreateThread() failed: %s.", SDL_GetError());
  459. return iRet;
  460. }
  461. else {
  462. m_hostapi->Debug(MEDIA_LOG_DEBUG, "create %s success, and thread id is %u.", SDL_GetThreadName(m_mediaplay_tid), SDL_GetThreadID(m_mediaplay_tid));
  463. bool bmediaplay_thread_exit = false;
  464. do {
  465. int iWaitRet = SDL_SemWaitTimeout(m_mediaplay_started_sem, 10);
  466. if (0 != iWaitRet) {
  467. if (SDL_MUTEX_TIMEDOUT == iWaitRet) {
  468. if (m_bmediaplay_started_flag) {
  469. break;
  470. }
  471. else {
  472. if (m_bmediaplay_start_failed) {
  473. m_hostapi->Debug(MEDIA_LOG_ERROR, "media play start failed.");
  474. break;
  475. }
  476. }
  477. }
  478. }
  479. else {
  480. bmediaplay_thread_exit = true;
  481. }
  482. } while (!bmediaplay_thread_exit);
  483. }
  484. SDL_DestroySemaphore(m_mediaplay_started_sem);
  485. m_mediaplay_started_sem = NULL;
  486. SDL_UnlockMutex(m_meida_play_start_wait_mutex);
  487. SDL_WaitThread(m_mediaplay_tid, NULL);
  488. m_mediaplay_tid = NULL;
  489. if (NULL != m_player_stat->m_audio_decode_tid) {
  490. SDL_WaitThread(m_player_stat->m_audio_decode_tid, NULL);
  491. m_player_stat->m_audio_decode_tid = NULL;
  492. }
  493. if (m_player_stat->m_eMType == eVideo_Type) {
  494. if (NULL != m_player_stat->m_video_decode_tid) {
  495. SDL_WaitThread(m_player_stat->m_video_decode_tid, NULL);
  496. m_player_stat->m_video_decode_tid = NULL;
  497. }
  498. if (NULL != m_player_stat->m_video_playing_tid) {
  499. SDL_WaitThread(m_player_stat->m_video_playing_tid, NULL);
  500. m_player_stat->m_video_playing_tid = NULL;
  501. }
  502. }
  503. if (NULL != m_player_stat->m_read_tid) {
  504. SDL_WaitThread(m_player_stat->m_read_tid, NULL);
  505. m_player_stat->m_read_tid = NULL;
  506. }
  507. ExitMediaPlayingThread();
  508. iRet = 0;
  509. return iRet;
  510. }
  511. int CMediaPlayer::StopMediaPlay()
  512. {
  513. int iRet = -1;
  514. if (NULL == m_player_stat) {
  515. return iRet;
  516. }
  517. if (NULL != m_mediaplay_started_sem) {
  518. SDL_SemPost(m_mediaplay_started_sem);
  519. }
  520. m_player_stat->buser_stop = true;
  521. SDL_LockMutex(m_meida_play_start_wait_mutex);
  522. if (NULL != m_player_stat->m_audio_play_wait_sem) {
  523. SDL_SemPost(m_player_stat->m_audio_play_wait_sem);
  524. }
  525. packet_queue_abort(&m_player_stat->video_pkt_queue, m_hostapi);
  526. packet_queue_abort(&m_player_stat->audio_pkt_queue, m_hostapi);
  527. frame_queue_signal(&m_player_stat->video_frm_queue);
  528. frame_queue_signal(&m_player_stat->audio_frm_queue);
  529. SDL_UnlockMutex(m_meida_play_start_wait_mutex);
  530. iRet = 0;
  531. return iRet;
  532. }
  533. int CMediaPlayer::ExitMediaPlayingThread()
  534. {
  535. int iRet = -1;
  536. if (NULL == m_player_stat){
  537. return iRet;
  538. }
  539. if(eVideo_Type == m_player_stat->m_eMType){
  540. if (m_player_stat->sdl_video.texture) {
  541. SDL_DestroyTexture(m_player_stat->sdl_video.texture);
  542. }
  543. if (m_player_stat->sdl_video.renderer){
  544. SDL_DestroyRenderer(m_player_stat->sdl_video.renderer);
  545. }
  546. if (m_player_stat->sdl_video.window){
  547. SDL_DestroyWindow(m_player_stat->sdl_video.window);
  548. }
  549. }
  550. if (m_player_stat->m_prvc_cb){
  551. if (m_player_stat->m_prvc_cb->cb_play_media_finished) {
  552. m_player_stat->m_prvc_cb->cb_play_media_finished(m_player_stat->m_prvc_cb->user_data);
  553. }
  554. }
  555. UnInitialize_Player_Stat();
  556. m_bplaying = false;
  557. iRet = 0;
  558. return iRet;
  559. }
  560. int64_t CMediaPlayer::GetMediaPlayingThreadId()
  561. {
  562. int64_t iRet = 0;
  563. if (NULL != m_player_stat)
  564. {
  565. if (NULL != m_player_stat->m_read_tid)
  566. {
  567. iRet = SDL_GestureID(m_player_stat->m_read_tid);
  568. }
  569. }
  570. return iRet;
  571. }