player.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763
  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. m_hostapi->Debug(MEDIA_LOG_DEBUG, "initialize SDL success");
  119. }
  120. }
  121. }
  122. CMediaPlayer::~CMediaPlayer()
  123. {
  124. if (NULL != m_meida_play_start_wait_mutex) {
  125. SDL_DestroyMutex(m_meida_play_start_wait_mutex);
  126. m_meida_play_start_wait_mutex = NULL;
  127. }
  128. if (NULL != m_player_stat) {
  129. UnInitialize_Player_Stat();
  130. }
  131. if (NULL != m_piconpath) {
  132. av_free(m_piconpath);
  133. m_piconpath = NULL;
  134. }
  135. if (NULL != m_paudiodev){
  136. av_free(m_paudiodev);
  137. m_paudiodev = NULL;
  138. }
  139. if (--initialized == 0){
  140. SDL_Quit();
  141. m_hostapi->Debug(MEDIA_LOG_INFO, "SDL_Quit");
  142. }
  143. }
  144. static int audio_volume_callback(int* audiovolume, void* userdata)
  145. {
  146. CMediaPlayer* player = (CMediaPlayer*)userdata;
  147. *audiovolume = player->GetVolume();
  148. return 0;
  149. }
  150. static int audio_play_finished_callback(void* userdata)
  151. {
  152. CMediaPlayer* player = (CMediaPlayer*)userdata;
  153. if (NULL != player){
  154. player->SetFinishedFlag();
  155. }
  156. return 0;
  157. }
  158. static int mediaplay_thread_func(void* arg)
  159. {
  160. int iret = -1;
  161. int icount = 0;
  162. CMediaPlayer* pPlayer = (CMediaPlayer*)arg;
  163. pPlayer->GetMediaHostApi()->Debug(MEDIA_LOG_DEBUG, "************* enter mediaplay_thread func ************");
  164. if (0 == open_demux(pPlayer->GetPlayerStat())) {
  165. pPlayer->GetMediaHostApi()->Debug(MEDIA_LOG_DEBUG, "open_demux function call success.");
  166. }
  167. else {
  168. pPlayer->GetMediaHostApi()->Debug(MEDIA_LOG_ERROR, "open_demux function call failed.");
  169. return iret;
  170. }
  171. if (eVideo_Type == pPlayer->GetPlayerStat()->m_eMType) {
  172. iret = open_video(pPlayer->GetPlayerStat());
  173. if (0 != iret) {
  174. pPlayer->GetMediaHostApi()->Debug(MEDIA_LOG_ERROR, "open video failed.");
  175. pPlayer->StartMediaPlayFailed();
  176. return iret;
  177. }
  178. }
  179. iret = open_audio(pPlayer->GetPlayerStat());
  180. if (0 == iret) {
  181. bool baudioplay_thread_exit = false;
  182. do {
  183. if (NULL != pPlayer->GetPlayerStat()->m_audio_play_wait_sem) {
  184. int iWait = SDL_SemWaitTimeout(pPlayer->GetPlayerStat()->m_audio_play_wait_sem, 5);
  185. if (0 != iWait) {
  186. if (SDL_MUTEX_TIMEDOUT == iWait) {
  187. if (false == pPlayer->GetMediaPlayStartedFlag()) {
  188. pPlayer->SetMediaPlayStartedFlag(true);
  189. }
  190. }
  191. else {
  192. pPlayer->GetMediaHostApi()->Debug(MEDIA_LOG_ERROR, "SDL_SemWaitTimeout error.");
  193. }
  194. }
  195. else {
  196. pPlayer->GetMediaHostApi()->Debug(MEDIA_LOG_DEBUG, "---------------stop audio playing thread---------------");
  197. baudioplay_thread_exit = true;
  198. }
  199. }
  200. else {
  201. pPlayer->GetMediaHostApi()->Debug(MEDIA_LOG_ERROR, "invalid m_audio_play_wait_sem");
  202. baudioplay_thread_exit = true;
  203. }
  204. } while (!baudioplay_thread_exit);
  205. SDL_CloseAudioDevice(pPlayer->GetPlayerStat()->m_audio_dev);
  206. }
  207. else {
  208. pPlayer->StartMediaPlayFailed();
  209. return iret;
  210. }
  211. pPlayer->GetMediaHostApi()->Debug(MEDIA_LOG_DEBUG, "************* exit mediaplay_thread func ************");
  212. return iret;
  213. }
  214. bool CMediaPlayer::SetFinishedFlag()
  215. {
  216. if (NULL != m_player_stat){
  217. if (NULL != m_hostapi) {
  218. m_hostapi->Debug(MEDIA_LOG_DEBUG, "%s:%d set baudio_finished to true.", __FUNCTION__, __LINE__);
  219. }
  220. }
  221. else {
  222. if (NULL != m_hostapi) {
  223. m_hostapi->Debug(MEDIA_LOG_INFO, "%s:%d m_player_stat is null and set audio finished flag failed.", __FUNCTION__, __LINE__);
  224. }
  225. }
  226. return true;
  227. }
  228. uint8_t CMediaPlayer::GetVolume()
  229. {
  230. return m_uvolume;
  231. }
  232. eMediaType_t CMediaPlayer::GetPlayingMediaType()
  233. {
  234. return m_player_stat->m_eMType;
  235. }
  236. player_stat_t* CMediaPlayer::GetPlayerStat()
  237. {
  238. return m_player_stat;
  239. }
  240. CMediaHostApi* CMediaPlayer::GetMediaHostApi()
  241. {
  242. return m_hostapi;
  243. }
  244. bool CMediaPlayer::GetMediaPlayStartedFlag()
  245. {
  246. return m_bmediaplay_started_flag;
  247. }
  248. void CMediaPlayer::SetMediaPlayStartedFlag(bool bflag)
  249. {
  250. m_bmediaplay_started_flag = bflag;
  251. }
  252. void CMediaPlayer::StartMediaPlayFailed()
  253. {
  254. m_bmediaplay_start_failed = true;
  255. }
  256. SDL_mutex* CMediaPlayer::GetMeidaPlayStartWaitMutex()
  257. {
  258. return m_meida_play_start_wait_mutex;
  259. }
  260. int CMediaPlayer::Initialize_Player_Stat(rvc_media_player_param_t* pMedia_Player)
  261. {
  262. int iRet = -1;
  263. if (NULL == pMedia_Player) {
  264. return iRet;
  265. }
  266. if (NULL != m_player_stat) {
  267. UnInitialize_Player_Stat();
  268. }
  269. m_player_stat = (player_stat_t*)av_mallocz(sizeof(player_stat_t));
  270. if (NULL == m_player_stat) {
  271. m_hostapi->Debug(MEDIA_LOG_ERROR, "player_stat_t struct malloc failed!");
  272. return iRet;
  273. }
  274. m_player_stat->buser_stop = false;
  275. m_player_stat->rvc_hostapi = m_hostapi;
  276. m_player_stat->m_prvc_cb = pMedia_Player->cb;
  277. m_player_stat->m_eMType = pMedia_Player->eType;
  278. m_player_stat->m_eWindType = pMedia_Player->m_eWindType;
  279. m_player_stat->bvice_monitor = pMedia_Player->bvicemonitor;
  280. m_player_stat->iDisplayCx = pMedia_Player->idisplaycx;
  281. m_player_stat->iDisplayCy = pMedia_Player->idisplaycy;
  282. m_player_stat->iDisplayWidth = pMedia_Player->idisplaywidth;
  283. m_player_stat->iDisplayHeight = pMedia_Player->idisplayheight;
  284. m_player_stat->on_audio_volume = &audio_volume_callback;
  285. m_player_stat->on_audio_play_finished = &audio_play_finished_callback;
  286. m_player_stat->user_data = this;
  287. if (NULL != m_piconpath){
  288. m_player_stat->m_piconpath = av_strdup(m_piconpath);
  289. }
  290. if (NULL != m_paudiodev){
  291. m_player_stat->m_paudiodev = av_strdup(m_paudiodev);
  292. }
  293. m_player_stat->uVolume = m_uvolume;
  294. m_player_stat->m_uFilesCount = pMedia_Player->m_uFilesCount;
  295. m_player_stat->m_icurrent_index = 0;
  296. m_player_stat->m_iaudio_dec_index = 0;
  297. for (size_t i = 0; i < pMedia_Player->m_uFilesCount; i++){
  298. memcpy(m_player_stat->m_strPlayLists[i], pMedia_Player->m_strPlayLists[i], strlen(pMedia_Player->m_strPlayLists[i]));
  299. }
  300. 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) {
  301. UnInitialize_Player_Stat();
  302. return iRet;
  303. }
  304. else{
  305. iRet = 0;
  306. }
  307. return iRet;
  308. }
  309. int CMediaPlayer::UnInitialize_Player_Stat()
  310. {
  311. /* XXX: use a special url_shutdown call to abort parse cleanly */
  312. if (NULL == m_player_stat) {
  313. return -1;
  314. }
  315. for (int index = 0; index < m_player_stat->m_uFilesCount; index++) {
  316. if (NULL != m_player_stat->m_pfmt_ctx[index]) {
  317. avformat_close_input(&m_player_stat->m_pfmt_ctx[index]);
  318. avformat_free_context(m_player_stat->m_pfmt_ctx[index]);
  319. m_player_stat->m_pfmt_ctx[index] = NULL;
  320. }
  321. if (NULL != m_player_stat->m_pacodec_ctx[index]) {
  322. avcodec_close(m_player_stat->m_pacodec_ctx[index]);
  323. avcodec_free_context(&m_player_stat->m_pacodec_ctx[index]);
  324. }
  325. if (NULL != m_player_stat->m_pvcodec_ctx[index]) {
  326. avcodec_close(m_player_stat->m_pvcodec_ctx[index]);
  327. avcodec_free_context(&m_player_stat->m_pvcodec_ctx[index]);
  328. }
  329. }
  330. SDL_DestroyCond(m_player_stat->m_continue_read_thread);
  331. m_hostapi->Debug(MEDIA_LOG_DEBUG, "SDL_DestroySemaphore m_audio_play_wait_sem.");
  332. SDL_DestroySemaphore(m_player_stat->m_audio_play_wait_sem);
  333. m_player_stat->m_audio_play_wait_sem = NULL;
  334. if (m_player_stat->m_eMType == eVideo_Type) {
  335. for (int index = 0; index < m_player_stat->m_uFilesCount; index++) {
  336. if (NULL != m_player_stat->m_pimg_convert_ctx[index]) {
  337. sws_freeContext(m_player_stat->m_pimg_convert_ctx[index]);
  338. m_player_stat->m_pimg_convert_ctx[index] = NULL;
  339. }
  340. if (NULL != m_player_stat->m_pfrm_yuv[index]) {
  341. av_frame_free(&m_player_stat->m_pfrm_yuv[index]);
  342. av_frame_unref(m_player_stat->m_pfrm_yuv[index]);
  343. }
  344. if (NULL != m_player_stat->m_pvideo_buffer[index]) {
  345. av_free(m_player_stat->m_pvideo_buffer[index]);
  346. m_player_stat->m_pvideo_buffer[index] = NULL;
  347. }
  348. }
  349. }
  350. packet_queue_destroy(&m_player_stat->video_pkt_queue, m_hostapi);
  351. packet_queue_destroy(&m_player_stat->audio_pkt_queue, m_hostapi);
  352. ///* free all pictures */
  353. frame_queue_destory(&m_player_stat->video_frm_queue);
  354. frame_queue_destory(&m_player_stat->audio_frm_queue);
  355. m_hostapi->Debug(MEDIA_LOG_DEBUG, "av_free player_stat_t.");
  356. swr_free(&m_player_stat->m_paudio_swr_ctx);
  357. //if (NULL != m_player_stat->m_paudio_frm) {
  358. // av_free(m_player_stat->m_paudio_frm);
  359. // m_player_stat->m_paudio_frm = NULL;
  360. //}
  361. if (NULL != m_player_stat->m_paudio_frm_rwr) {
  362. av_free(m_player_stat->m_paudio_frm_rwr);
  363. m_player_stat->m_paudio_frm_rwr = NULL;
  364. }
  365. if (m_player_stat->m_piconpath){
  366. av_free(m_player_stat->m_piconpath);
  367. m_player_stat->m_piconpath = NULL;
  368. }
  369. if (m_player_stat->m_paudiodev) {
  370. av_free(m_player_stat->m_paudiodev);
  371. m_player_stat->m_paudiodev = NULL;
  372. }
  373. if (m_player_stat->m_straudiodev) {
  374. av_free(m_player_stat->m_straudiodev);
  375. m_player_stat->m_straudiodev = NULL;
  376. }
  377. av_free(m_player_stat);
  378. m_player_stat = NULL;
  379. return 0;
  380. }
  381. int CMediaPlayer::GetViceVideoDisplayInfo(int* icx, int* icy, int* iwidth, int* iheight)
  382. {
  383. int iRet = -1;
  384. size_t uCount = SDL_GetNumVideoDisplays();
  385. m_hostapi->Debug(MEDIA_LOG_DEBUG, "VideoDisplays Number is %d.", uCount);
  386. SDL_DisplayMode dispalymode[RVC_MAX_DISPLAYNUM] = { 0 };
  387. for (size_t i = 0; i < uCount && i < RVC_MAX_DISPLAYNUM; i++) {
  388. SDL_GetDesktopDisplayMode(i, &dispalymode[i]);
  389. m_hostapi->Debug(MEDIA_LOG_DEBUG, "VideoDisplays{%d} format = %d", i, dispalymode[i].format);
  390. m_hostapi->Debug(MEDIA_LOG_DEBUG, "VideoDisplays{%d} w = %d", i, dispalymode[i].w);
  391. m_hostapi->Debug(MEDIA_LOG_DEBUG, "VideoDisplays{%d} h = %d", i, dispalymode[i].h);
  392. m_hostapi->Debug(MEDIA_LOG_DEBUG, "VideoDisplays{%d} refresh_rate = %d", i, dispalymode[i].refresh_rate);
  393. }
  394. if (uCount > 1) {
  395. *icx = dispalymode[0].w;
  396. *icy = 0;
  397. *iwidth = dispalymode[1].w;
  398. *iheight = dispalymode[1].h;
  399. iRet = 0;
  400. }
  401. return iRet;
  402. }
  403. int CMediaPlayer::InitParam(rvc_media_player_param_t* pMedia_Player)
  404. {
  405. int iRet = -1;
  406. if (0 != Initialize_Player_Stat(pMedia_Player)){
  407. return iRet;
  408. }
  409. m_hostapi->Debug(MEDIA_LOG_DEBUG, "initialize player stat success.");
  410. /* start video display */
  411. if (frame_queue_init(&m_player_stat->video_frm_queue, &m_player_stat->video_pkt_queue, VIDEO_PICTURE_QUEUE_SIZE, 1) < 0 ||
  412. frame_queue_init(&m_player_stat->audio_frm_queue, &m_player_stat->audio_pkt_queue, SAMPLE_QUEUE_SIZE, 1) < 0)
  413. {
  414. m_hostapi->Debug(MEDIA_LOG_DEBUG, "media frame queue init failed!");
  415. UnInitialize_Player_Stat();
  416. return iRet;
  417. }
  418. else{
  419. m_hostapi->Debug(MEDIA_LOG_DEBUG, "frame queue init success!");
  420. }
  421. /* init packet queue */
  422. if (packet_queue_init(&m_player_stat->video_pkt_queue, m_hostapi) < 0 ||
  423. packet_queue_init(&m_player_stat->audio_pkt_queue, m_hostapi) < 0)
  424. {
  425. m_hostapi->Debug(MEDIA_LOG_DEBUG, "media packet queue init failed!");
  426. UnInitialize_Player_Stat();
  427. return iRet;
  428. }
  429. else{
  430. m_hostapi->Debug(MEDIA_LOG_DEBUG, "packet queue init success!");
  431. }
  432. /* put end pkt into packet queue */
  433. AVPacket flush_pkt = {0};
  434. flush_pkt.data = NULL;
  435. packet_queue_put(&m_player_stat->video_pkt_queue, &flush_pkt, m_hostapi);
  436. packet_queue_put(&m_player_stat->audio_pkt_queue, &flush_pkt, m_hostapi);
  437. if (!(m_player_stat->m_continue_read_thread = SDL_CreateCond())){
  438. m_hostapi->Debug(MEDIA_LOG_DEBUG, "SDL_CreateCond(): %s.", SDL_GetError());
  439. UnInitialize_Player_Stat();
  440. return iRet;
  441. }
  442. m_player_stat->m_audio_play_wait_sem = SDL_CreateSemaphore(0);
  443. init_clock(&m_player_stat->video_clk, &m_player_stat->video_pkt_queue.serial);
  444. init_clock(&m_player_stat->audio_clk, &m_player_stat->audio_pkt_queue.serial);
  445. if (m_player_stat->bvice_monitor){
  446. if (0 == GetViceVideoDisplayInfo(&m_player_stat->iDisplayCx, &m_player_stat->iDisplayCy, &m_player_stat->iDisplayWidth, &m_player_stat->iDisplayHeight)){
  447. m_hostapi->Debug(MEDIA_LOG_DEBUG, "Get Vice Video Display Info Success.");
  448. }
  449. }
  450. m_hostapi->Debug(MEDIA_LOG_DEBUG, "display cx is %d, cy is %d, width is %d, height is %d.", m_player_stat->iDisplayCx, m_player_stat->iDisplayCy, m_player_stat->iDisplayWidth, m_player_stat->iDisplayHeight);
  451. iRet = 0;
  452. return iRet;
  453. }
  454. int CMediaPlayer::SetVolume(uint8_t uVolume)
  455. {
  456. int iRet = -1;
  457. m_uvolume = uVolume * SDL_MIX_MAXVOLUME/100;
  458. m_hostapi->Debug(MEDIA_LOG_DEBUG, "set audio volume(%d) to %d.", uVolume, m_uvolume);
  459. iRet = 0;
  460. return iRet;
  461. }
  462. bool CMediaPlayer::GetPlayingFlag()
  463. {
  464. return m_bplaying;
  465. }
  466. int CMediaPlayer::StartMediaPlay()
  467. {
  468. int iRet = -1;
  469. m_bplaying = true;
  470. SDL_LockMutex(m_meida_play_start_wait_mutex);
  471. m_bmediaplay_started_flag = false;
  472. m_bmediaplay_start_failed = false;
  473. m_mediaplay_started_sem = SDL_CreateSemaphore(0);
  474. m_mediaplay_tid = SDL_CreateThread(mediaplay_thread_func, "mediaplay_thread", this);
  475. if (NULL == m_mediaplay_tid) {
  476. SDL_UnlockMutex(m_meida_play_start_wait_mutex);
  477. m_hostapi->Debug(MEDIA_LOG_ERROR, "SDL_CreateThread() failed: %s.", SDL_GetError());
  478. return iRet;
  479. }
  480. else {
  481. m_hostapi->Debug(MEDIA_LOG_DEBUG, "create %s success, and thread id is %u.", SDL_GetThreadName(m_mediaplay_tid), SDL_GetThreadID(m_mediaplay_tid));
  482. bool bmediaplay_thread_exit = false;
  483. do {
  484. int iWaitRet = SDL_SemWaitTimeout(m_mediaplay_started_sem, 10);
  485. if (0 != iWaitRet) {
  486. if (SDL_MUTEX_TIMEDOUT == iWaitRet) {
  487. if (m_bmediaplay_started_flag) {
  488. m_hostapi->Debug(MEDIA_LOG_INFO, "media play is already started.");
  489. break;
  490. }
  491. else {
  492. if (m_bmediaplay_start_failed) {
  493. m_hostapi->Debug(MEDIA_LOG_ERROR, "media play start failed.");
  494. break;
  495. }
  496. }
  497. }
  498. }
  499. else {
  500. m_hostapi->Debug(MEDIA_LOG_INFO, "start media play thread has exit.");
  501. bmediaplay_thread_exit = true;
  502. }
  503. } while (!bmediaplay_thread_exit);
  504. }
  505. SDL_DestroySemaphore(m_mediaplay_started_sem);
  506. m_mediaplay_started_sem = NULL;
  507. SDL_UnlockMutex(m_meida_play_start_wait_mutex);
  508. m_hostapi->Debug(MEDIA_LOG_DEBUG, "wait media play thread.");
  509. SDL_WaitThread(m_mediaplay_tid, NULL);
  510. m_mediaplay_tid = NULL;
  511. m_hostapi->Debug(MEDIA_LOG_DEBUG, "media play thread finished.");
  512. if (NULL != m_player_stat->m_audio_decode_tid) {
  513. m_hostapi->Debug(MEDIA_LOG_DEBUG, "wait audio decode thread.");
  514. SDL_WaitThread(m_player_stat->m_audio_decode_tid, NULL);
  515. m_player_stat->m_audio_decode_tid = NULL;
  516. m_hostapi->Debug(MEDIA_LOG_DEBUG, "audio decode thread finished.");
  517. }
  518. if (m_player_stat->m_eMType == eVideo_Type) {
  519. if (NULL != m_player_stat->m_video_decode_tid) {
  520. m_hostapi->Debug(MEDIA_LOG_DEBUG, "wait video decode thread.");
  521. SDL_WaitThread(m_player_stat->m_video_decode_tid, NULL);
  522. m_player_stat->m_video_decode_tid = NULL;
  523. m_hostapi->Debug(MEDIA_LOG_DEBUG, "video decode thread finished.");
  524. }
  525. if (NULL != m_player_stat->m_video_playing_tid) {
  526. m_hostapi->Debug(MEDIA_LOG_DEBUG, "wait video playing thread.");
  527. SDL_WaitThread(m_player_stat->m_video_playing_tid, NULL);
  528. m_player_stat->m_video_playing_tid = NULL;
  529. m_hostapi->Debug(MEDIA_LOG_DEBUG, "video playing thread finished.");
  530. }
  531. }
  532. if (NULL != m_player_stat->m_read_tid) {
  533. SDL_WaitThread(m_player_stat->m_read_tid, NULL);
  534. m_player_stat->m_read_tid = NULL;
  535. m_hostapi->Debug(MEDIA_LOG_DEBUG, "demux thread finished.");
  536. }
  537. ExitMediaPlayingThread();
  538. iRet = 0;
  539. return iRet;
  540. }
  541. int CMediaPlayer::StopMediaPlay()
  542. {
  543. int iRet = -1;
  544. m_hostapi->Debug(MEDIA_LOG_DEBUG, "StopMediaPlay called.");
  545. if (NULL == m_player_stat) {
  546. return iRet;
  547. }
  548. if (NULL != m_mediaplay_started_sem) {
  549. SDL_SemPost(m_mediaplay_started_sem);
  550. }
  551. m_player_stat->buser_stop = true;
  552. SDL_LockMutex(m_meida_play_start_wait_mutex);
  553. if (NULL != m_player_stat->m_audio_play_wait_sem) {
  554. m_hostapi->Debug(MEDIA_LOG_DEBUG, "SDL_SemPost m_audio_play_wait_sem.");
  555. SDL_SemPost(m_player_stat->m_audio_play_wait_sem);
  556. }
  557. packet_queue_abort(&m_player_stat->video_pkt_queue, m_hostapi);
  558. packet_queue_abort(&m_player_stat->audio_pkt_queue, m_hostapi);
  559. frame_queue_signal(&m_player_stat->video_frm_queue);
  560. frame_queue_signal(&m_player_stat->audio_frm_queue);
  561. m_hostapi->Debug(MEDIA_LOG_DEBUG, "set m_player_stat media finished flag to true.");
  562. SDL_UnlockMutex(m_meida_play_start_wait_mutex);
  563. iRet = 0;
  564. m_hostapi->Debug(MEDIA_LOG_DEBUG, "StopMediaPlay exit.");
  565. return iRet;
  566. }
  567. int CMediaPlayer::ExitMediaPlayingThread()
  568. {
  569. int iRet = -1;
  570. if (NULL == m_player_stat){
  571. return iRet;
  572. }
  573. m_hostapi->Debug(MEDIA_LOG_DEBUG, "enter ExitMediaPlayingThread call.");
  574. if(eVideo_Type == m_player_stat->m_eMType){
  575. if (m_player_stat->sdl_video.texture) {
  576. SDL_DestroyTexture(m_player_stat->sdl_video.texture);
  577. }
  578. if (m_player_stat->sdl_video.renderer){
  579. SDL_DestroyRenderer(m_player_stat->sdl_video.renderer);
  580. }
  581. if (m_player_stat->sdl_video.window){
  582. SDL_DestroyWindow(m_player_stat->sdl_video.window);
  583. m_hostapi->Debug(MEDIA_LOG_DEBUG, "Destroy Window.");
  584. }
  585. }
  586. if (m_player_stat->m_prvc_cb){
  587. m_hostapi->Debug(MEDIA_LOG_DEBUG, "cb_play_media_finished callback.");
  588. if (m_player_stat->m_prvc_cb->cb_play_media_finished) {
  589. m_player_stat->m_prvc_cb->cb_play_media_finished(m_player_stat->m_prvc_cb->user_data);
  590. }
  591. }
  592. UnInitialize_Player_Stat();
  593. m_bplaying = false;
  594. iRet = 0;
  595. m_hostapi->Debug(MEDIA_LOG_DEBUG, "Leave ExitMediaPlayingThread call.");
  596. return iRet;
  597. }
  598. int64_t CMediaPlayer::GetMediaPlayingThreadId()
  599. {
  600. int64_t iRet = 0;
  601. if (NULL != m_player_stat)
  602. {
  603. if (NULL != m_player_stat->m_read_tid)
  604. {
  605. iRet = SDL_GestureID(m_player_stat->m_read_tid);
  606. }
  607. }
  608. return iRet;
  609. }