player.cpp 20 KB

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