OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
wxMediaCtrl3 Class Reference

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/slic3r/GUI/wxMediaCtrl3.h>

Inheritance diagram for wxMediaCtrl3:
Collaboration diagram for wxMediaCtrl3:

Public Member Functions

 wxMediaCtrl3 (wxWindow *parent)
 ~wxMediaCtrl3 () override
void Load (wxURI url) override
void Play () override
void Stop () override
void SetExternalFrame (const wxImage &frame, wxSize videoSize)
void BeginExternalStream ()
void EndExternalStream ()
void SetIdleImage (wxString const &image)
wxMediaState GetState () override
int GetLastError () const override
wxSize GetVideoSize () const override

Protected Member Functions

void paintEvent (wxPaintEvent &evt)
wxSize DoGetBestSize () const override
void DoSetSize (int x, int y, int width, int height, int sizeFlags) override
void PlayThread ()
int PlayFfmpeg (std::shared_ptr< wxURI > const &url, std::unique_lock< std::mutex > &lock)
void NotifyStopped ()

Static Protected Member Functions

static void bambu_log (void *ctx, int level, tchar const *msg)
static int ffmpeg_interrupt_callback (void *opaque)

Private Attributes

wxString m_idle_image
wxMediaState m_state = wxMEDIASTATE_STOPPED
int m_error = 0
wxSize m_video_size = wxDefaultSize
wxSize m_frame_size = wxDefaultSize
wxImage m_frame
std::shared_ptr< wxURI > m_url
std::shared_ptr< wxURI > m_active_url
bool m_external = false
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::condition_variable m_cond
std::thread m_thread
std::atomic_bool m_refresh_pending {false}

Detailed Description

Constructor & Destructor Documentation

◆ wxMediaCtrl3()

wxMediaCtrl3::wxMediaCtrl3 ( wxWindow * parent)
49 : wxWindow(parent, wxID_ANY)
50 , BambuLib(StaticBambuLib::get(this))
51 , m_thread([this] { PlayThread(); })
52{
53 SetBackgroundColour("#000001ff");
54}
std::thread m_thread
Definition wxMediaCtrl3.h:105
void PlayThread()
Definition wxMediaCtrl3.cpp:475
static StaticBambuLib & get(BambuLib *copy=nullptr)
Definition PrinterFileSystem.cpp:1857

References m_thread, and PlayThread().

Referenced by bambu_log(), and ffmpeg_interrupt_callback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ~wxMediaCtrl3()

wxMediaCtrl3::~wxMediaCtrl3 ( )
override
57{
58 {
59 std::unique_lock<std::mutex> lk(m_mutex);
60 m_url.reset(new wxURI);
61 m_frame = wxImage(m_idle_image);
62 m_cond.notify_all();
63 }
64 m_thread.join();
65}
std::condition_variable m_cond
Definition wxMediaCtrl3.h:104
wxString m_idle_image
Definition wxMediaCtrl3.h:86
wxImage m_frame
Definition wxMediaCtrl3.h:94
std::shared_ptr< wxURI > m_url
Definition wxMediaCtrl3.h:97
std::mutex m_mutex
Definition wxMediaCtrl3.h:103

References m_cond, m_frame, m_idle_image, m_mutex, m_thread, and m_url.

Member Function Documentation

◆ bambu_log()

void wxMediaCtrl3::bambu_log ( void * ctx,
int level,
tchar const * msg )
staticprotected
243{
244#ifdef _WIN32
245 wxString msg(msg2);
246#else
247 wxString msg = wxString::FromUTF8(msg2);
248#endif
249 if (level == 1) {
250 if (msg.EndsWith("]")) {
251 int n = msg.find_last_of('[');
252 if (n != wxString::npos) {
253 long val = 0;
254 wxMediaCtrl3 *ctrl = (wxMediaCtrl3 *) ctx;
255 if (msg.SubString(n + 1, msg.Length() - 2).ToLong(&val)) {
256 std::unique_lock<std::mutex> lk(ctrl->m_mutex);
257 ctrl->m_error = (int) val;
258 }
259 }
260 } else if (msg.Contains("stat_log")) {
261 wxCommandEvent evt(EVT_MEDIA_CTRL_STAT);
262 wxMediaCtrl3 *ctrl = (wxMediaCtrl3 *) ctx;
263 evt.SetEventObject(ctrl);
264 evt.SetString(msg.Mid(msg.Find(' ') + 1));
265 wxPostEvent(ctrl, evt);
266 }
267 }
268 BOOST_LOG_TRIVIAL(info) << msg.ToUTF8().data();
269}
wxMediaCtrl3(wxWindow *parent)
Definition wxMediaCtrl3.cpp:48
int m_error
Definition wxMediaCtrl3.h:88

References wxMediaCtrl3(), m_error, and m_mutex.

Referenced by PlayThread().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ BeginExternalStream()

void wxMediaCtrl3::BeginExternalStream ( )
137{
138 std::unique_lock<std::mutex> lk(m_mutex);
139 m_external = true;
140 m_url.reset();
141 m_active_url.reset();
142 m_video_size = wxDefaultSize;
143 m_frame = wxImage(m_idle_image);
144 m_cond.notify_all();
145 Refresh();
146}
wxSize m_video_size
Definition wxMediaCtrl3.h:89
std::shared_ptr< wxURI > m_active_url
Definition wxMediaCtrl3.h:98
bool m_external
Definition wxMediaCtrl3.h:99

References m_active_url, m_cond, m_external, m_frame, m_idle_image, m_mutex, m_url, and m_video_size.

◆ DoGetBestSize()

wxSize wxMediaCtrl3::DoGetBestSize ( ) const
overrideprotected
192{
193 return {-1, -1};
194}

◆ DoSetSize()

void wxMediaCtrl3::DoSetSize ( int x,
int y,
int width,
int height,
int sizeFlags )
overrideprotected
233{
234 wxWindow::DoSetSize(x, y, width, height, sizeFlags);
235 if (sizeFlags == wxSIZE_USE_EXISTING) return;
236 wxMediaCtrl_OnSize(this, m_video_size, width, height);
237 std::unique_lock<std::mutex> lk(m_mutex);
239 Refresh();
240}
wxSize m_frame_size
Definition wxMediaCtrl3.h:90
static void adjust_frame_size(wxSize &frame, wxSize const &video, wxSize const &window)
Definition wxMediaCtrl3.cpp:196
void wxMediaCtrl_OnSize(wxWindow *ctrl, wxSize const &videoSize, int width, int height)
Definition MediaPlayCtrl.cpp:1115

References adjust_frame_size(), m_frame_size, m_mutex, m_video_size, and wxMediaCtrl_OnSize().

Here is the call graph for this function:

◆ EndExternalStream()

void wxMediaCtrl3::EndExternalStream ( )
149{
150 std::unique_lock<std::mutex> lk(m_mutex);
151 m_external = false;
152 m_url.reset();
153 m_active_url.reset();
154 m_video_size = wxDefaultSize;
155 m_frame = wxImage(m_idle_image);
156 m_cond.notify_all();
157 Refresh();
158}

References m_active_url, m_cond, m_external, m_frame, m_idle_image, m_mutex, m_url, and m_video_size.

◆ ffmpeg_interrupt_callback()

int wxMediaCtrl3::ffmpeg_interrupt_callback ( void * opaque)
staticprotected
324{
325 auto *ctrl = static_cast<wxMediaCtrl3 *>(opaque);
326 std::lock_guard<std::mutex> lock(ctrl->m_mutex);
327 return ctrl->m_url != ctrl->m_active_url;
328}
@ lock
Definition GLGizmoEmboss.cpp:209

References wxMediaCtrl3().

Referenced by PlayFfmpeg().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetLastError()

int wxMediaCtrl3::GetLastError ( ) const
overridevirtual

Reimplemented from Slic3r::GUI::IMediaController.

180{
181 std::unique_lock<std::mutex> lk(m_mutex);
182 return m_error;
183}

References m_error, and m_mutex.

◆ GetState()

wxMediaState wxMediaCtrl3::GetState ( )
overridevirtual

Reimplemented from Slic3r::GUI::IMediaController.

174{
175 std::unique_lock<std::mutex> lk(m_mutex);
176 return m_state;
177}
wxMediaState m_state
Definition wxMediaCtrl3.h:87

References m_mutex, and m_state.

◆ GetVideoSize()

wxSize wxMediaCtrl3::GetVideoSize ( ) const
overridevirtual

Reimplemented from Slic3r::GUI::IMediaController.

186{
187 std::unique_lock<std::mutex> lk(m_mutex);
188 return m_video_size;
189}

References m_mutex, and m_video_size.

◆ Load()

void wxMediaCtrl3::Load ( wxURI url)
overridevirtual

Implements Slic3r::GUI::IMediaController.

70{
71 std::unique_lock<std::mutex> lk(m_mutex);
72 if (m_external)
73 return;
74 m_video_size = wxDefaultSize;
75 m_error = 0;
76 m_url.reset(new wxURI(url));
77 m_cond.notify_all();
78}

References m_cond, m_error, m_external, m_mutex, m_url, and m_video_size.

◆ NotifyStopped()

void wxMediaCtrl3::NotifyStopped ( )
protected
602{
603 m_state = wxMEDIASTATE_STOPPED;
604 wxMediaEvent event(wxEVT_MEDIA_STATECHANGED);
605 event.SetId(GetId());
606 event.SetEventObject(this);
607 wxPostEvent(this, event);
608}

References m_state.

Referenced by PlayFfmpeg(), PlayThread(), and Stop().

Here is the caller graph for this function:

◆ paintEvent()

void wxMediaCtrl3::paintEvent ( wxPaintEvent & evt)
protected
205{
206 wxPaintDC dc(this);
207 auto size = GetSize();
208 if (size.x <= 0 || size.y <= 0)
209 return;
210 std::unique_lock<std::mutex> lk(m_mutex);
211 if (!m_frame.IsOk())
212 return;
213 auto size2 = m_frame.GetSize();
214 if (size2.x != m_frame_size.x && size2.y == m_frame_size.y)
215 size2.x = m_frame_size.x;
216 auto size3 = (size - size2) / 2;
217 if (size2.x != size.x && size2.y != size.y) {
218 double scale = 1.;
219 if (size.x * size2.y > size.y * size2.x) {
220 size3 = {size.x * size2.y / size.y, size2.y};
221 scale = double(size.y) / size2.y;
222 } else {
223 size3 = {size2.x, size.y * size2.x / size.x};
224 scale = double(size.x) / size2.x;
225 }
226 dc.SetUserScale(scale, scale);
227 size3 = (size3 - size2) / 2;
228 }
229 dc.DrawBitmap(m_frame, size3.x, size3.y);
230}
int scale(const int val)
Definition WipeTowerDialog.cpp:58

References m_frame, m_frame_size, m_mutex, and scale().

Referenced by wxDEFINE_EVENT().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Play()

void wxMediaCtrl3::Play ( )
overridevirtual

Implements Slic3r::GUI::IMediaController.

81{
82 std::unique_lock<std::mutex> lk(m_mutex);
83 if (m_external)
84 return;
85 if (m_state != wxMEDIASTATE_PLAYING) {
86 m_state = wxMEDIASTATE_PLAYING;
87 wxMediaEvent event(wxEVT_MEDIA_STATECHANGED);
88 event.SetId(GetId());
89 event.SetEventObject(this);
90 wxPostEvent(this, event);
91 }
92}

References m_external, m_mutex, and m_state.

◆ PlayFfmpeg()

int wxMediaCtrl3::PlayFfmpeg ( std::shared_ptr< wxURI > const & url,
std::unique_lock< std::mutex > & lock )
protected
331{
332 static std::once_flag logger_once;
333 std::call_once(logger_once, install_ffmpeg_logger);
334
335 if (avformat_network_init() < 0)
336 return 2;
337
338 AVFormatContext *format_context = avformat_alloc_context();
339 if (!format_context) {
340 avformat_network_deinit();
341 return 2;
342 }
343
344 format_context->interrupt_callback = {&wxMediaCtrl3::ffmpeg_interrupt_callback, this};
345 format_context->flags |= AVFMT_FLAG_NOBUFFER;
346 format_context->max_delay = 0;
347 m_active_url = url;
348
349 auto finish = [&](int error) {
350 lock.unlock();
351 avformat_close_input(&format_context);
352 avformat_network_deinit();
353 lock.lock();
354 m_active_url.reset();
355 return error;
356 };
357
358 const std::string uri = url->BuildURI().ToUTF8().data();
359 const wxString scheme = url->GetScheme();
360 const bool http_stream = scheme.CmpNoCase("http") == 0 || scheme.CmpNoCase("https") == 0;
361 AVDictionary *options = nullptr;
362 if (http_stream) {
363 // Live multipart MJPEG. fflags=nobuffer / AVFMT_FLAG_NOBUFFER / max_delay=0
364 // (set above) are the low-latency levers - they disable the demuxer
365 // read-ahead queue. probesize / analyzeduration only bound the one-off
366 // avformat_find_stream_info() at open; a 32-byte budget returned before a
367 // whole JPEG frame was seen, so width/height came back unset and the open
368 // was rejected. Give it room to identify one frame (a startup cost only).
369 // rw_timeout / timeout bound a wedged connect or read so a stale stream
370 // fails fast and is retried, instead of the reader thread hanging.
371 // avioflags=direct is deliberately NOT set: unbuffered reads make the
372 // mpjpeg demuxer emit "Packet corrupt" and bail on any short read across
373 // a multipart boundary.
374 av_dict_set(&options, "fflags", "nobuffer", 0);
375 av_dict_set(&options, "probesize", "5000000", 0);
376 av_dict_set(&options, "analyzeduration", "1000000", 0);
377 av_dict_set(&options, "rw_timeout", "5000000", 0);
378 av_dict_set(&options, "timeout", "5000000", 0);
379 } else {
380 av_dict_set(&options, "rtsp_transport", "tcp", 0);
381 }
382 lock.unlock();
383 int error = avformat_open_input(&format_context, uri.c_str(), nullptr, &options);
384 av_dict_free(&options);
385 lock.lock();
386 if (error < 0)
387 return finish(2);
388
389 lock.unlock();
390 error = avformat_find_stream_info(format_context, nullptr);
391 lock.lock();
392 if (error < 0)
393 return finish(2);
394
395 const int video_stream = av_find_best_stream(format_context, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0);
396 if (video_stream < 0)
397 return finish(2);
398
399 AVVideoDecoder decoder;
400 if (decoder.open(*format_context->streams[video_stream]->codecpar) < 0)
401 return finish(2);
402
403 // Prefer the dimensions the container reported. A small probe budget, or a
404 // camera that doesn't announce a size up front, can leave these unset - in
405 // that case fill them in from the first frame that decodes (below) rather
406 // than failing the open outright.
407 auto apply_video_size = [&](wxSize size) {
408 if (!size.IsFullySpecified() || size.x <= 0 || size.y <= 0)
409 return false;
410 m_video_size = size;
413 return true;
414 };
415 bool have_size = apply_video_size({format_context->streams[video_stream]->codecpar->width,
416 format_context->streams[video_stream]->codecpar->height});
417 int size_probe_frames = 0; // frames spent still waiting for a usable size
418
419 AVPacket *packet = av_packet_alloc();
420 if (!packet)
421 return finish(2);
422
423 while (m_url == url) {
424 lock.unlock();
425 error = av_read_frame(format_context, packet);
426 lock.lock();
427 if (m_url != url)
428 break;
429 if (error < 0)
430 break;
431 if (packet->stream_index == video_stream) {
432 const int decode_error = decoder.decode(*packet);
433 if (decode_error == 0) {
434 if (!have_size) {
435 have_size = apply_video_size(decoder.decoded_frame_size());
436 if (!have_size) {
437 av_packet_unref(packet);
438 // MJPEG yields a sized frame on the first full packet; if
439 // several seconds of frames never do, treat it as a bad
440 // stream instead of sitting in "Loading..." forever.
441 if (++size_probe_frames > 120)
442 break;
443 continue;
444 }
445 }
446 auto frame_size = m_frame_size;
447 lock.unlock();
448#ifdef _WIN32
449 wxBitmap frame;
450 decoder.toWxBitmap(frame, frame_size);
451#else
452 wxImage frame;
453 decoder.toWxImage(frame, frame_size);
454#endif
455 lock.lock();
456 if (m_url != url)
457 break;
458 if (frame.IsOk())
459 m_frame = frame;
460 if (!m_refresh_pending.exchange(true)) {
461 CallAfter([this] {
462 m_refresh_pending.store(false);
463 Refresh();
464 });
465 }
466 }
467 }
468 av_packet_unref(packet);
469 }
470
471 av_packet_free(&packet);
472 return finish(m_url == url ? 2 : 1);
473}
bool toWxBitmap(wxBitmap &bitmap, wxSize const &size)
Definition AVVideoDecoder.cpp:164
wxSize decoded_frame_size() const
Definition AVVideoDecoder.hpp:46
int decode(Bambu_Sample const &sample)
Definition AVVideoDecoder.cpp:75
bool toWxImage(wxImage &image, wxSize const &size)
Definition AVVideoDecoder.cpp:120
int open(Bambu_StreamInfo const &info)
Definition AVVideoDecoder.cpp:34
std::atomic_bool m_refresh_pending
Definition wxMediaCtrl3.h:106
static int ffmpeg_interrupt_callback(void *opaque)
Definition wxMediaCtrl3.cpp:323
void NotifyStopped()
Definition wxMediaCtrl3.cpp:601
static void install_ffmpeg_logger()
Definition wxMediaCtrl3.cpp:317

References adjust_frame_size(), AVVideoDecoder::decode(), AVVideoDecoder::decoded_frame_size(), ffmpeg_interrupt_callback(), install_ffmpeg_logger(), m_active_url, m_frame, m_frame_size, m_refresh_pending, m_url, m_video_size, NotifyStopped(), AVVideoDecoder::open(), AVVideoDecoder::toWxBitmap(), and AVVideoDecoder::toWxImage().

Referenced by PlayThread().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PlayThread()

void wxMediaCtrl3::PlayThread ( )
protected
476{
477 using namespace std::chrono_literals;
478 std::shared_ptr<wxURI> url;
479 std::unique_lock<std::mutex> lk(m_mutex);
480 while (true) {
481 m_cond.wait(lk, [this, &url] { return m_url != url; });
482 url = m_url;
483 if (url == nullptr)
484 continue;
485 if (!url->HasScheme())
486 break;
487 const wxString scheme = url->GetScheme();
488 const bool generic_ffmpeg = scheme.CmpNoCase("http") == 0 || scheme.CmpNoCase("https") == 0 ||
489 scheme.CmpNoCase("rtsp") == 0 || scheme.CmpNoCase("rtsps") == 0;
490 int error = 0;
491 if (generic_ffmpeg) {
492 error = PlayFfmpeg(url, lk);
493 } else {
494 lk.unlock();
495 Bambu_Tunnel tunnel = nullptr;
496 error = Bambu_Create(&tunnel, m_url->BuildURI().ToUTF8());
497 if (error == 0) {
499 error = Bambu_Open(tunnel);
500 if (error == 0)
501 error = Bambu_would_block;
502 }
503 lk.lock();
504 while (error == int(Bambu_would_block)) {
505 m_cond.wait_for(lk, 100ms);
506 if (m_url != url) {
507 error = 1;
508 break;
509 }
510 lk.unlock();
511 error = Bambu_StartStream(tunnel, true);
512 lk.lock();
513 }
514 Bambu_StreamInfo info;
515 if (error == 0)
516 error = Bambu_GetStreamInfo(tunnel, 0, &info);
517 AVVideoDecoder decoder;
518 int minFrameDuration = 0;
519 if (error == 0) {
520 decoder.open(info);
521 m_video_size = { info.format.video.width, info.format.video.height };
523 minFrameDuration = 800 / info.format.video.frame_rate; // 80%
525 }
526 Bambu_Sample sample;
527 while (error == 0) {
528 lk.unlock();
529 error = Bambu_ReadSample(tunnel, &sample);
530 lk.lock();
531 while (error == int(Bambu_would_block)) {
532 m_cond.wait_for(lk, 100ms);
533 if (m_url != url) {
534 error = 1;
535 break;
536 }
537 lk.unlock();
538 error = Bambu_ReadSample(tunnel, &sample);
539 lk.lock();
540 }
541 if (error == 0) {
542 auto frame_size = m_frame_size;
543 lk.unlock();
544 decoder.decode(sample);
545#ifdef _WIN32
546 wxBitmap bm;
547 decoder.toWxBitmap(bm, frame_size);
548#else
549 wxImage bm;
550 decoder.toWxImage(bm, frame_size);
551#endif
552 lk.lock();
553 if (m_url != url) {
554 error = 1;
555 break;
556 }
557 if (bm.IsOk()) {
558 auto now = std::chrono::system_clock::now();
559 if (m_last_PTS && (sample.decode_time - m_last_PTS) < 30000000ULL) { // 3s
560 auto next_PTS_expected = m_last_PTS_expected + std::chrono::milliseconds((sample.decode_time - m_last_PTS) / 10000ULL);
561 // The frame is late, catch up a little
562 auto next_PTS_practical = m_last_PTS_practical + std::chrono::milliseconds(minFrameDuration);
563 auto next_PTS = std::max(next_PTS_expected, next_PTS_practical);
564 if(now < next_PTS)
565 std::this_thread::sleep_until(next_PTS);
566 else
567 next_PTS = now;
568 //auto text = wxString::Format(L"wxMediaCtrl3 pts diff %ld\n", std::chrono::duration_cast<std::chrono::milliseconds>(next_PTS - next_PTS_expected).count());
569 //OutputDebugString(text);
570 m_last_PTS = sample.decode_time;
571 m_last_PTS_expected = next_PTS_expected;
572 m_last_PTS_practical = next_PTS;
573 } else {
574 // Resync
575 m_last_PTS = sample.decode_time;
578 }
579 m_frame = bm;
580 }
581 CallAfter([this] { Refresh(); });
582 }
583 }
584 if (tunnel) {
585 lk.unlock();
586 Bambu_Close(tunnel);
587 Bambu_Destroy(tunnel);
588 tunnel = nullptr;
589 lk.lock();
590 }
591 }
592 if (m_url == url)
593 m_error = error;
594 m_frame_size = wxDefaultSize;
595 m_video_size = wxDefaultSize;
597 }
598
599}
struct __Bambu_Sample Bambu_Sample
@ Bambu_would_block
Definition BambuTunnel.h:108
BAMBU_EXPORT int BAMBU_FUNC Bambu_StartStream(Bambu_Tunnel tunnel, bool video)
unsigned long long decode_time
Definition BambuTunnel.h:101
BAMBU_EXPORT int BAMBU_FUNC Bambu_ReadSample(Bambu_Tunnel tunnel, Bambu_Sample *sample)
struct __Bambu_StreamInfo Bambu_StreamInfo
BAMBU_EXPORT void BAMBU_FUNC Bambu_Destroy(Bambu_Tunnel tunnel)
BAMBU_EXPORT void BAMBU_FUNC Bambu_Close(Bambu_Tunnel tunnel)
union __Bambu_StreamInfo::@170065151325210153066214006343241035305375173333 format
BAMBU_EXPORT int BAMBU_FUNC Bambu_Open(Bambu_Tunnel tunnel)
void * Bambu_Tunnel
Definition BambuTunnel.h:36
BAMBU_EXPORT void BAMBU_FUNC Bambu_SetLogger(Bambu_Tunnel tunnel, Logger logger, void *context)
BAMBU_EXPORT int BAMBU_FUNC Bambu_Create(Bambu_Tunnel *tunnel, char const *path)
BAMBU_EXPORT int BAMBU_FUNC Bambu_GetStreamInfo(Bambu_Tunnel tunnel, int index, Bambu_StreamInfo *info)
int PlayFfmpeg(std::shared_ptr< wxURI > const &url, std::unique_lock< std::mutex > &lock)
Definition wxMediaCtrl3.cpp:330
std::chrono::system_clock::time_point m_last_PTS_expected
Definition wxMediaCtrl3.h:101
static void bambu_log(void *ctx, int level, tchar const *msg)
Definition wxMediaCtrl3.cpp:242
std::chrono::system_clock::time_point m_last_PTS_practical
Definition wxMediaCtrl3.h:102
std::uint64_t m_last_PTS
Definition wxMediaCtrl3.h:100

References adjust_frame_size(), Bambu_Close(), Bambu_Create(), Bambu_Destroy(), Bambu_GetStreamInfo(), bambu_log(), Bambu_Open(), Bambu_ReadSample(), Bambu_SetLogger(), Bambu_StartStream(), Bambu_would_block, AVVideoDecoder::decode(), __Bambu_Sample::decode_time, __Bambu_StreamInfo::format, m_cond, m_error, m_frame, m_frame_size, m_last_PTS, m_last_PTS_expected, m_last_PTS_practical, m_mutex, m_url, m_video_size, NotifyStopped(), AVVideoDecoder::open(), PlayFfmpeg(), AVVideoDecoder::toWxBitmap(), and AVVideoDecoder::toWxImage().

Referenced by wxMediaCtrl3().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetExternalFrame()

void wxMediaCtrl3::SetExternalFrame ( const wxImage & frame,
wxSize videoSize )
105{
106 if (!frame.IsOk())
107 return;
108 {
109 std::unique_lock<std::mutex> lk(m_mutex);
110 if (!m_external)
111 return;
112 m_frame = frame;
113 m_video_size = videoSize.IsFullySpecified() ? videoSize : frame.GetSize();
115 }
116 CallAfter([this] { Refresh(); });
117}

References adjust_frame_size(), m_external, m_frame, m_frame_size, m_mutex, and m_video_size.

Here is the call graph for this function:

◆ SetIdleImage()

void wxMediaCtrl3::SetIdleImage ( wxString const & image)
161{
162 if (m_idle_image == image)
163 return;
164 m_idle_image = image;
165 if (m_url == nullptr) {
166 std::unique_lock<std::mutex> lk(m_mutex);
167 m_frame = wxImage(m_idle_image);
168 assert(m_frame.IsOk());
169 Refresh();
170 }
171}

References m_frame, m_idle_image, m_mutex, and m_url.

◆ Stop()

void wxMediaCtrl3::Stop ( )
overridevirtual

Implements Slic3r::GUI::IMediaController.

95{
96 std::unique_lock<std::mutex> lk(m_mutex);
97 m_url.reset();
98 m_frame = wxImage(m_idle_image);
100 m_cond.notify_all();
101 Refresh();
102}

References m_cond, m_frame, m_idle_image, m_mutex, m_url, and NotifyStopped().

Here is the call graph for this function:

Member Data Documentation

◆ m_active_url

std::shared_ptr<wxURI> wxMediaCtrl3::m_active_url
private

◆ m_cond

std::condition_variable wxMediaCtrl3::m_cond
private

◆ m_error

int wxMediaCtrl3::m_error = 0
private

◆ m_external

bool wxMediaCtrl3::m_external = false
private

◆ m_frame

◆ m_frame_size

wxSize wxMediaCtrl3::m_frame_size = wxDefaultSize
private

◆ m_idle_image

wxString wxMediaCtrl3::m_idle_image
private

◆ m_last_PTS

std::uint64_t wxMediaCtrl3::m_last_PTS {0}
private
100{0};

Referenced by PlayThread().

◆ m_last_PTS_expected

std::chrono::system_clock::time_point wxMediaCtrl3::m_last_PTS_expected
private

Referenced by PlayThread().

◆ m_last_PTS_practical

std::chrono::system_clock::time_point wxMediaCtrl3::m_last_PTS_practical
private

Referenced by PlayThread().

◆ m_mutex

◆ m_refresh_pending

std::atomic_bool wxMediaCtrl3::m_refresh_pending {false}
private
106{false};

Referenced by PlayFfmpeg().

◆ m_state

wxMediaState wxMediaCtrl3::m_state = wxMEDIASTATE_STOPPED
private

Referenced by GetState(), NotifyStopped(), and Play().

◆ m_thread

std::thread wxMediaCtrl3::m_thread
private

Referenced by wxMediaCtrl3(), and ~wxMediaCtrl3().

◆ m_url

std::shared_ptr<wxURI> wxMediaCtrl3::m_url
private

◆ m_video_size

wxSize wxMediaCtrl3::m_video_size = wxDefaultSize
private

The documentation for this class was generated from the following files: