📄 sync.cpp
字号:
state = process_msg_queue(SYNC_STATE_WAIT_AUDIO); if (state == SYNC_STATE_WAIT_AUDIO) { if (m_waiting_for_audio != 0) { SDL_SemWaitTimeout(m_sync_sem, 10); } else { // make sure we set the current time get_current_time(); sync_message(LOG_DEBUG, "Current time is "U64, m_current_time); return (SYNC_STATE_PLAYING); } } return (state);}/* * sync_thread_playing - do the work of displaying the video and making * sure we're in sync. */int CPlayerSession::sync_thread_playing (void) { int state; uint64_t audio_resync_time = 0; int64_t wait_audio_time; bool video_have_next_time = false; uint64_t video_next_time; bool have_audio_eof = false; bool need_audio_restart = false; bool need_audio_resync = false; bool have_video_eof = false; state = process_msg_queue(SYNC_STATE_PLAYING); if (state == SYNC_STATE_PLAYING) { get_current_time(); if (m_audio_sync) { need_audio_resync = m_audio_sync->check_audio_sync(m_current_time, audio_resync_time, wait_audio_time, have_audio_eof, need_audio_restart); if (need_audio_resync) { if (m_timed_sync_list) { // wait for video to play out if (config.GetBoolValue(CONFIG_SHORT_VIDEO_RENDER)) { // flush timed sync for (CTimedSync *ts = m_timed_sync_list; ts != NULL; ts = ts->GetNext()) { ts->flush_sync_buffers(); ts->flush_decode_buffers(); } return SYNC_STATE_WAIT_AUDIO_READY; } return SYNC_STATE_AUDIO_RESYNC; } else { // skip right to the audio return SYNC_STATE_WAIT_SYNC; } } } video_next_time = MAX_UINT64; if (m_timed_sync_list != NULL) { have_video_eof = true; for (CTimedSync *ts = m_timed_sync_list; ts != NULL; ts = ts->GetNext()) { uint64_t cmp; bool have_eof = false; if (ts->play_at(m_current_time, false, cmp, have_eof)) { video_have_next_time = true;#if 0 sync_message(LOG_DEBUG, "return "U64 " "U64 " %u", cmp, m_current_time, have_eof);#endif video_next_time = MIN(cmp, video_next_time); } have_video_eof &= have_eof; } } int delay = 0; bool have_delay = false; if (m_timed_sync_list && m_audio_sync) { if (have_video_eof && have_audio_eof) { return (SYNC_STATE_DONE); } if (video_have_next_time) { have_delay = true; int64_t video_wait_time = video_next_time - m_current_time; delay = (int)video_wait_time; } } else if (m_timed_sync_list) { if (have_video_eof) { sync_message(LOG_DEBUG, "have video eof %d", have_video_eof); return (SYNC_STATE_DONE); } if (video_have_next_time) { have_delay = true; delay = (int)(video_next_time - m_current_time); } } else { // audio only if (have_audio_eof) { return (SYNC_STATE_DONE); } if (audio_resync_time != 0) { have_delay = true; delay = (int)(audio_resync_time - m_current_time); } } if (have_delay) {#if 0 if (delay >= 9) { delay = 9; SDL_SemWaitTimeout(m_sync_sem, delay); }#else //sync_message(LOG_DEBUG, "delay %d", delay); if (delay >= 10) { delay = 10; } SDL_SemWaitTimeout(m_sync_sem, delay);#endif } else { SDL_SemWaitTimeout(m_sync_sem, 10); } } return (state);}/* * sync_thread_pause - wait for messages to continue or finish */int CPlayerSession::sync_thread_paused (void){ int state; state = process_msg_queue(SYNC_STATE_PAUSED); if (state == SYNC_STATE_PAUSED) { SDL_SemWaitTimeout(m_sync_sem, 10); } return (state);}/* * sync_thread_pause - wait for messages to exit, pretty much. */int CPlayerSession::sync_thread_done (void){ int state; state = process_msg_queue(SYNC_STATE_DONE); if (state == SYNC_STATE_DONE) { SDL_SemWaitTimeout(m_sync_sem, 10); } return (state);}int CPlayerSession::sync_thread_wait_audio_ready (void){ int state; state = process_msg_queue(SYNC_STATE_WAIT_AUDIO_READY); if (state == SYNC_STATE_WAIT_AUDIO_READY) { uint64_t astart = 0; if (m_audio_sync->is_audio_ready(astart) == 1) { m_first_time_played = astart; m_current_time = astart; m_waiting_for_audio = 1; m_audio_sync->play_audio(); return SYNC_STATE_WAIT_TIMED_INIT; } SDL_Delay(10); } return state;}int CPlayerSession::sync_thread_wait_timed_init (void){ int state; state = process_msg_queue(SYNC_STATE_WAIT_TIMED_INIT); if (state == SYNC_STATE_WAIT_TIMED_INIT) { bool have_audio_eof = false; bool need_audio_restart = false; bool need_audio_resync = false; uint64_t audio_resync_time = 0; int64_t wait_audio_time; get_current_time(); need_audio_resync = m_audio_sync->check_audio_sync(m_current_time, audio_resync_time, wait_audio_time, have_audio_eof, need_audio_restart); if (need_audio_resync) { for (CTimedSync *ts = m_timed_sync_list; ts != NULL; ts = ts->GetNext()) { ts->flush_sync_buffers(); ts->flush_decode_buffers(); } return SYNC_STATE_WAIT_AUDIO_READY; } uint failed; bool any_inited; if (initialize_timed_sync(failed, any_inited)) { return SYNC_STATE_PLAYING; } // need to add failure case here. SDL_Delay(10); } return state;}int CPlayerSession::sync_thread_audio_resync (void) { int state; uint64_t audio_resync_time = 0; int64_t wait_audio_time; bool video_have_next_time = false; uint64_t video_next_time; bool have_audio_eof = false; bool need_audio_resync = false; bool have_video_eof = false; bool need_audio_restart = false; state = process_msg_queue(SYNC_STATE_AUDIO_RESYNC); if (state == SYNC_STATE_AUDIO_RESYNC) { get_current_time(); need_audio_resync = m_audio_sync->check_audio_sync(m_current_time, audio_resync_time, wait_audio_time, have_audio_eof, need_audio_restart); if (need_audio_restart) { // this occurs when the time is in the past, but we're continuing // video return SYNC_STATE_WAIT_SYNC; } if (need_audio_resync == false) { // video continued, so, restart audio sync_message(LOG_ERR, "resync but no audio resync"); return SYNC_STATE_PLAYING; } have_video_eof = true; video_next_time = MAX_UINT64; for (CTimedSync *ts = m_timed_sync_list; ts != NULL; ts = ts->GetNext()) { uint64_t cmp; bool have_eof; if (ts->play_at(m_current_time, true, cmp, have_eof)) { video_have_next_time = true; video_next_time = MIN(cmp, video_next_time); have_video_eof &= have_eof; } } sync_message(LOG_DEBUG, "audio resync - "U64" have_next %d "U64, m_current_time, video_have_next_time, video_next_time); sync_message(LOG_DEBUG, "audio time "U64, audio_resync_time); if (have_audio_eof && have_video_eof) { return SYNC_STATE_DONE; } if (video_have_next_time == false) { SDL_SemWaitTimeout(m_sync_sem, 10); } else { int64_t diff = video_next_time - audio_resync_time; if (diff >= TO_D64(-5000) && diff <= TO_D64(5000)) { return SYNC_STATE_WAIT_SYNC; } diff = video_next_time - m_current_time; if (diff < 0 || diff > TO_D64(1000)) { // drop this frame return SYNC_STATE_WAIT_SYNC; } if (diff > 9) { diff = 9; } if (diff >= 9) { int delay = (int)diff; SDL_SemWaitTimeout(m_sync_sem, delay); } } } return state;}/* * sync_thread - call the correct handler, and wait for the state changes. * Each handler should only return the new state... */ int CPlayerSession::sync_thread (int state){ int newstate = 0; process_sdl_events(); switch (state) { case SYNC_STATE_INIT: m_session_state = SESSION_BUFFERING; newstate = sync_thread_init(); break; case SYNC_STATE_WAIT_SYNC: newstate = sync_thread_wait_sync(); break; case SYNC_STATE_WAIT_AUDIO: newstate = sync_thread_wait_audio(); break; case SYNC_STATE_PLAYING: newstate = sync_thread_playing(); break; case SYNC_STATE_PAUSED: newstate = sync_thread_paused(); break; case SYNC_STATE_AUDIO_RESYNC: newstate = sync_thread_audio_resync(); break; case SYNC_STATE_DONE: newstate = sync_thread_done(); break; case SYNC_STATE_WAIT_AUDIO_READY: newstate = sync_thread_wait_audio_ready(); break; case SYNC_STATE_WAIT_TIMED_INIT: newstate = sync_thread_wait_timed_init(); break; case SYNC_STATE_EXIT: newstate = SYNC_STATE_EXIT; break; }#ifdef DEBUG_SYNC_STATE if (state != newstate) sync_message(LOG_INFO, "sync changed state %s to %s", sync_state[state], sync_state[newstate]);#endif if (state != newstate) { state = newstate; switch (state) { case SYNC_STATE_WAIT_SYNC: case SYNC_STATE_WAIT_AUDIO_READY: m_session_state = SESSION_BUFFERING; break; case SYNC_STATE_WAIT_AUDIO: case SYNC_STATE_AUDIO_RESYNC: break; case SYNC_STATE_WAIT_TIMED_INIT: case SYNC_STATE_PLAYING: m_session_state = SESSION_PLAYING; break; case SYNC_STATE_PAUSED: { for (CTimedSync *ts = m_timed_sync_list; ts != NULL; ts = ts->GetNext()) { ts->flush_sync_buffers(); } if (m_audio_sync != NULL) m_audio_sync->flush_sync_buffers(); m_session_state = SESSION_PAUSED; m_sync_pause_done = 1; break; } case SYNC_STATE_DONE: { CVideoSync *vs = m_video_list; while (vs != NULL) { if (vs->get_fullscreen() != 0) { vs->set_fullscreen(0); vs->do_video_resize(); } vs = vs->GetNextVideo(); } m_master_msg_queue->send_message(MSG_SESSION_FINISHED, m_master_msg_queue_sem); m_session_state = SESSION_DONE; break; } case SYNC_STATE_EXIT: { for (CTimedSync *ts = m_timed_sync_list; ts != NULL; ts = ts->GetNext()) { ts->flush_sync_buffers(); } if (m_audio_sync != NULL) m_audio_sync->flush_sync_buffers(); break; } } } return (state);}int c_sync_thread (void *data){ CPlayerSession *p; int state = SYNC_STATE_INIT; p = (CPlayerSession *)data; if (p->start_session_work() == false) { state = SYNC_STATE_EXIT; } do { state = p->sync_thread(state); } while (state != SYNC_STATE_EXIT); return (0);}void CPlayerSession::display_status (void){ sync_message(LOG_DEBUG, "*******************************************************************"); sync_message(LOG_DEBUG, "current time "U64, m_current_time); CPlayerMedia *p = m_my_media; while (p != NULL) { p->display_status(); p = p->get_next(); }}/* end sync.cpp */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -