Skip to content

Commit

Permalink
MOT/GTK: show transmission progress
Browse files Browse the repository at this point in the history
Show a progress bar as long as the next slide is being received.
  • Loading branch information
basicmaster committed Aug 20, 2022
1 parent 2675f14 commit 5557f3d
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 10 deletions.
9 changes: 8 additions & 1 deletion README.md
Expand Up @@ -625,6 +625,13 @@ and the current service signals to transmit a Slideshow, the Slideshow
window is displayed. It shows a slide after it has been received
completely and without errors.

While the next slide is being received, a progress bar at the bottom of
the Slideshow window shows the fraction that has successfully been
received so far. It is always updated after a new segment has arrived
free from error. The first segments of the initial slide usually are
received before the corresponding header comes by. In this case a
pulsing bar is shown until the header is available.

Currently the following limitations apply:

* slideshows in a separate sub-channel are not supported (just X-PAD);
Expand All @@ -640,7 +647,7 @@ This software is licensed under the GNU General Public License Version 3
*Please note that the included FEC lib by KA9Q has a separate license!*

DABlin - capital DAB experience
Copyright (C) 2015-2021 Stefan Pöschel
Copyright (C) 2015-2022 Stefan Pöschel

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down
9 changes: 8 additions & 1 deletion src/dablin_gtk.cpp
@@ -1,6 +1,6 @@
/*
DABlin - capital DAB experience
Copyright (C) 2015-2021 Stefan Pöschel
Copyright (C) 2015-2022 Stefan Pöschel
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -264,6 +264,7 @@ DABlinGTK::DABlinGTK(DABlinGTKOptions options) {
fic_change_service.GetDispatcher().connect(sigc::mem_fun(*this, &DABlinGTK::FICChangeServiceEmitted));
pad_change_dynamic_label.GetDispatcher().connect(sigc::mem_fun(*this, &DABlinGTK::PADChangeDynamicLabelEmitted));
pad_change_slide.GetDispatcher().connect(sigc::mem_fun(*this, &DABlinGTK::PADChangeSlideEmitted));
pad_file_progress.GetDispatcher().connect(sigc::mem_fun(*this, &DABlinGTK::PADFileProgressEmitted));
do_rec_status_update.GetDispatcher().connect(sigc::mem_fun(*this, &DABlinGTK::DoRecStatusUpdateEmitted));
do_datetime_sync.GetDispatcher().connect(sigc::mem_fun(*this, &DABlinGTK::DoDateTimeSyncEmitted));
do_datetime_update.GetDispatcher().connect(sigc::mem_fun(*this, &DABlinGTK::DoDateTimeUpdateEmitted));
Expand Down Expand Up @@ -1338,6 +1339,12 @@ void DABlinGTK::PADChangeSlideEmitted() {
slideshow_window.TryToShow();
}

void DABlinGTK::PADFileProgressEmitted() {
// fprintf(stderr, "### PADFileProgressEmitted\n");

slideshow_window.UpdateFileProgress(pad_file_progress.Pop());
}

void DABlinGTK::PADLengthError(size_t /*announced_xpad_len*/, size_t /*xpad_len*/) {
fprintf(stderr, "\x1B[31m" "[X-PAD len]" "\x1B[0m" " ");
}
6 changes: 5 additions & 1 deletion src/dablin_gtk.h
@@ -1,6 +1,6 @@
/*
DABlin - capital DAB experience
Copyright (C) 2015-2021 Stefan Pöschel
Copyright (C) 2015-2022 Stefan Pöschel
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -326,6 +326,10 @@ class DABlinGTK : public Gtk::Window, EnsembleSourceObserver, EnsemblePlayerObse
void PADChangeSlide(const MOT_FILE& slide) {pad_change_slide.PushAndEmit(slide);}
void PADChangeSlideEmitted();

GTKDispatcherQueue<double> pad_file_progress;
void PADFileProgress(const double fraction) {pad_file_progress.PushAndEmit(fraction);}
void PADFileProgressEmitted();

void PADLengthError(size_t announced_xpad_len, size_t xpad_len);
public:
DABlinGTK(DABlinGTKOptions options);
Expand Down
16 changes: 15 additions & 1 deletion src/dablin_gtk_sls.cpp
@@ -1,6 +1,6 @@
/*
DABlin - capital DAB experience
Copyright (C) 2018-2021 Stefan Pöschel
Copyright (C) 2018-2022 Stefan Pöschel
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -36,6 +36,7 @@ DABlinGTKSlideshowWindow::DABlinGTKSlideshowWindow() {

top_grid.attach(image, 0, 0, 1, 1);
top_grid.attach_next_to(link_button, image, Gtk::POS_BOTTOM, 1, 1);
top_grid.attach_next_to(progress_file, link_button, Gtk::POS_BOTTOM, 1, 1);

show_all_children();

Expand Down Expand Up @@ -98,6 +99,7 @@ void DABlinGTKSlideshowWindow::AwaitSlide() {
image.set_tooltip_text("Waiting for slide...");

link_button.hide();
progress_file.hide();
}

void DABlinGTKSlideshowWindow::UpdateSlide(const MOT_FILE& slide) {
Expand Down Expand Up @@ -153,4 +155,16 @@ void DABlinGTKSlideshowWindow::UpdateSlide(const MOT_FILE& slide) {
} else {
link_button.hide();
}

// hide file progress
progress_file.hide();
}

void DABlinGTKSlideshowWindow::UpdateFileProgress(const double fraction) {
// update/show file progress
if(fraction == -1)
progress_file.pulse(); // unknown progress
else
progress_file.set_fraction(fraction);
progress_file.show();
}
4 changes: 3 additions & 1 deletion src/dablin_gtk_sls.h
@@ -1,6 +1,6 @@
/*
DABlin - capital DAB experience
Copyright (C) 2018-2021 Stefan Pöschel
Copyright (C) 2018-2022 Stefan Pöschel
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -33,6 +33,7 @@ class DABlinGTKSlideshowWindow : public Gtk::Window {
Gtk::Grid top_grid;
Gtk::Image image;
Gtk::LinkButton link_button;
Gtk::ProgressBar progress_file;

Glib::RefPtr<Gdk::Pixbuf> pixbuf_waiting;
int prev_parent_x;
Expand All @@ -47,6 +48,7 @@ class DABlinGTKSlideshowWindow : public Gtk::Window {

void AwaitSlide();
void UpdateSlide(const MOT_FILE& slide);
void UpdateFileProgress(const double fraction);
void ClearSlide() {image.clear();}
bool IsEmptySlide() {return image.get_storage_type() == Gtk::ImageType::IMAGE_EMPTY;}
};
Expand Down
19 changes: 15 additions & 4 deletions src/mot_manager.cpp
Expand Up @@ -196,7 +196,7 @@ bool MOTObject::IsToBeShown() {
// abort, if incomplete/not yet triggered
if(!header_received)
return false;
if(!body.IsFinished() || result_file.body_size != body.GetSize())
if(!body.IsFinished() || GetCurrentBodySize() != GetTotalBodySize())
return false;
if(!result_file.trigger_time_now)
return false;
Expand Down Expand Up @@ -298,7 +298,7 @@ void MOTManager::HandleMOTDataGroup(const std::vector<uint8_t>& dg) {
return;


// add segment to MOT object (reset if necessary)
// add completed segment to MOT object (reset if necessary)
if(current_transport_id != transport_id) {
current_transport_id = transport_id;
object = MOTObject();
Expand All @@ -307,8 +307,19 @@ void MOTManager::HandleMOTDataGroup(const std::vector<uint8_t>& dg) {

// check if object shall be shown
bool display = object.IsToBeShown();
// fprintf(stderr, "dg_type: %d, seg_number: %2d%s, transport_id: %5d, size: %4zu; display: %s\n",
// dg_type, seg_number, last_seg ? " (LAST)" : "", transport_id, seg_size, display ? "true" : "false");

// derive progress fraction (-1 = unknown, as header not yet received - but body segments)
double fraction = object.GetTotalBodySize() ? (double) object.GetCurrentBodySize() / (double) object.GetTotalBodySize() : -1;

// fprintf(stderr, "dg_type: %d, seg_number: %2d%s, transport_id: %5d, seg_size: %4zu; display: %s, curr/total body size: %5zu/%5zu, fraction: %f\n",
// dg_type, seg_number, last_seg ? " (LAST)" : "", transport_id, seg_size, display ? "true" : "false", object.GetCurrentBodySize(), object.GetTotalBodySize(), fraction);

/* update progress
* - if unknown, update invoked for each segment for visible pulse()!
* - if complete, only update when shown
*/
if(!(fraction == 1 && !display))
observer->MOTFileProgress(fraction);

// if object shall be shown, forward it
if(display)
Expand Down
6 changes: 5 additions & 1 deletion src/mot_manager.h
Expand Up @@ -52,7 +52,7 @@ struct MOT_FILE {
static const int CONTENT_SUB_TYPE_HEADER_UPDATE = 0x000;

MOT_FILE() :
body_size(-1),
body_size(0),
content_type(-1),
content_sub_type(-1),
trigger_time_now(false)
Expand Down Expand Up @@ -101,6 +101,9 @@ class MOTObject {
void AddSeg(bool dg_type_header, int seg_number, bool last_seg, const uint8_t* data, size_t len);
bool IsToBeShown();
MOT_FILE GetFile() {return result_file;}

size_t GetCurrentBodySize() {return body.GetSize();}
size_t GetTotalBodySize() {return result_file.body_size;}
};


Expand All @@ -110,6 +113,7 @@ class MOTManagerObserver {
virtual ~MOTManagerObserver() {}

virtual void MOTFileCompleted(const MOT_FILE& /*file*/) {}
virtual void MOTFileProgress(const double /*fraction*/) {}
};


Expand Down
2 changes: 2 additions & 0 deletions src/pad_decoder.h
Expand Up @@ -205,6 +205,7 @@ class PADDecoderObserver {

virtual void PADChangeDynamicLabel(const DL_STATE& /*dl*/) {}
virtual void PADChangeSlide(const MOT_FILE& /*slide*/) {}
virtual void PADFileProgress(const double /*fraction*/) {}

virtual void PADLengthError(size_t /*announced_xpad_len*/, size_t /*xpad_len*/) {}
};
Expand All @@ -226,6 +227,7 @@ class PADDecoder : public MOTManagerObserver {
MOTManager *mot_manager;

void MOTFileCompleted(const MOT_FILE& file);
void MOTFileProgress(const double fraction) {observer->PADFileProgress(fraction);}
public:
PADDecoder(PADDecoderObserver *observer, bool loose);
~PADDecoder();
Expand Down

0 comments on commit 5557f3d

Please sign in to comment.