ENH: wxMediaCtrl3 display video frame at pts
Change-Id: I8847236d2307101e5f2befc6477cd20b3691841c Jira: none
This commit is contained in:
parent
e709ddacc8
commit
05328da461
|
@ -221,10 +221,12 @@ void wxMediaCtrl3::PlayThread()
|
||||||
if (error == 0)
|
if (error == 0)
|
||||||
error = Bambu_GetStreamInfo(tunnel, 0, &info);
|
error = Bambu_GetStreamInfo(tunnel, 0, &info);
|
||||||
AVVideoDecoder decoder;
|
AVVideoDecoder decoder;
|
||||||
|
int minFrameDuration = 0;
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
decoder.open(info);
|
decoder.open(info);
|
||||||
m_video_size = { info.format.video.width, info.format.video.height };
|
m_video_size = { info.format.video.width, info.format.video.height };
|
||||||
adjust_frame_size(m_frame_size, m_video_size, GetSize());
|
adjust_frame_size(m_frame_size, m_video_size, GetSize());
|
||||||
|
minFrameDuration = 800 / info.format.video.frame_rate; // 80%
|
||||||
NotifyStopped();
|
NotifyStopped();
|
||||||
}
|
}
|
||||||
Bambu_Sample sample;
|
Bambu_Sample sample;
|
||||||
|
@ -258,8 +260,30 @@ void wxMediaCtrl3::PlayThread()
|
||||||
error = 1;
|
error = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (bm.IsOk())
|
if (bm.IsOk()) {
|
||||||
|
auto now = std::chrono::system_clock::now();
|
||||||
|
if (m_last_PTS && (sample.decode_time - m_last_PTS) < 30000000ULL) { // 3s
|
||||||
|
auto next_PTS_expected = m_last_PTS_expected + std::chrono::milliseconds((sample.decode_time - m_last_PTS) / 10000ULL);
|
||||||
|
// The frame is late, catch up a little
|
||||||
|
auto next_PTS_practical = m_last_PTS_practical + std::chrono::milliseconds(minFrameDuration);
|
||||||
|
auto next_PTS = std::max(next_PTS_expected, next_PTS_practical);
|
||||||
|
if(now < next_PTS)
|
||||||
|
std::this_thread::sleep_until(next_PTS);
|
||||||
|
else
|
||||||
|
next_PTS = now;
|
||||||
|
//auto text = wxString::Format(L"wxMediaCtrl3 pts diff %ld\n", std::chrono::duration_cast<std::chrono::milliseconds>(next_PTS - next_PTS_expected).count());
|
||||||
|
//OutputDebugString(text);
|
||||||
|
m_last_PTS = sample.decode_time;
|
||||||
|
m_last_PTS_expected = next_PTS_expected;
|
||||||
|
m_last_PTS_practical = next_PTS;
|
||||||
|
} else {
|
||||||
|
// Resync
|
||||||
|
m_last_PTS = sample.decode_time;
|
||||||
|
m_last_PTS_expected = now;
|
||||||
|
m_last_PTS_practical = now;
|
||||||
|
}
|
||||||
m_frame = bm;
|
m_frame = bm;
|
||||||
|
}
|
||||||
CallAfter([this] { Refresh(); });
|
CallAfter([this] { Refresh(); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,9 @@ private:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::shared_ptr<wxURI> m_url;
|
std::shared_ptr<wxURI> m_url;
|
||||||
|
std::uint64_t m_last_PTS{0};
|
||||||
|
std::chrono::system_clock::time_point m_last_PTS_expected;
|
||||||
|
std::chrono::system_clock::time_point m_last_PTS_practical;
|
||||||
std::mutex m_mutex;
|
std::mutex m_mutex;
|
||||||
std::condition_variable m_cond;
|
std::condition_variable m_cond;
|
||||||
std::thread m_thread;
|
std::thread m_thread;
|
||||||
|
|
Loading…
Reference in New Issue