8 #include <QDragEnterEvent> 14 #include <QProgressDialog> 18 #define QOI_IMPLEMENTATION 36 QWidget::paintEvent(event);
43 QPainter painter(
this);
44 painter.setRenderHint(QPainter::Antialiasing);
46 QSize rect_size =
event->rect().size();
47 QSize pix_size =
pix.size();
48 pix_size.scale(event->rect().size(), Qt::KeepAspectRatio);
50 QPoint corner((rect_size.width() - pix_size.width()) / 2,
51 (rect_size.height() - pix_size.height()) / 2);
53 QPixmap scaled_pix =
pix.scaled(pix_size,
55 Qt::SmoothTransformation);
56 painter.drawPixmap(corner, scaled_pix);
72 QMessageBox::warning(
this, QString::fromLatin1(
"QtAV error"),
73 tr(
"Can not create video renderer"));
82 ui->lineEditReference->installEventFilter(
this);
85 QString theme = settings.value(
"Preferences::theme",
"light").toString();
86 ui->clearButton->setIcon(
LoadSvg(
":/resources/svg/trash.svg", theme));
89 ui->verticalLayoutMain->addWidget(
_label, 1.0);
100 if(!filename.isEmpty() && QFileInfo::exists(filename))
104 ui->lineFilename->setText(filename);
109 ui->decodeButton->setEnabled(
true);
123 return ui->lineEditReference->text();
140 QString directory_path =
141 settings.value(
"VideoDialog.loadDirectory", QDir::currentPath()).toString();
143 QString filename = QFileDialog::getOpenFileName(
this, tr(
"Load Video"),
144 directory_path, tr(
"(*.*)"));
149 directory_path = QFileInfo(filename).absolutePath();
150 settings.setValue(
"VideoDialog.loadDirectory", directory_path);
155 const auto& fps =
_media_player->statistics().video.frame_rate;
157 int num_frames =
static_cast<int>(qreal(duration_ms) * fps / 1000.0);
158 ui->timeSlider->setRange(0, num_frames);
159 _media_player->setNotifyInterval( static_cast<int>(1000 / fps) );
162 ui->timeSlider->setEnabled(
true);
166 QMessageBox msgBox(
this);
167 msgBox.setWindowTitle(
"Video is not seekable");
168 msgBox.setText(tr(
"Video is not seekable. You will need to decode the video into individual frames.\n"));
169 msgBox.addButton(QMessageBox::Cancel);
170 QPushButton* button = msgBox.addButton(tr(
"Decode!"), QMessageBox::YesRole);
171 msgBox.setDefaultButton(button);
173 int res = msgBox.exec();
175 if (res < 0 || res == QMessageBox::Cancel)
177 ui->timeSlider->setEnabled(
false);
188 double period = 1000 / fps;
189 qint64 frame_pos =
static_cast<qint64
>(qreal(num) * period );
193 num = std::max(0, num);
197 void*
data =
qoi_decode( frame.data, frame.length, &frame.info, 3);
198 QImage image(static_cast<uchar*>(data), frame.info.width, frame.info.height, QImage::Format_RGB888);
215 if(
ui->radioButtonFrame->isChecked() )
217 ui->timeSlider->setValue(static_cast<int>(value));
219 else if(
ui->radioButtonTime->isChecked() )
221 const auto& fps =
_media_player->statistics().video.frame_rate;
222 ui->timeSlider->setValue( static_cast<int>( value * 1000 / fps ));
228 if( obj !=
ui->lineEditReference )
232 if (ev->type() == QEvent::DragEnter)
234 auto event =
static_cast<QDragEnterEvent*
>(ev);
235 const QMimeData* mimeData =
event->mimeData();
236 QStringList mimeFormats = mimeData->formats();
238 QString&
format = mimeFormats.front();
240 QByteArray encoded = mimeData->data(format);
241 QDataStream stream(&encoded, QIODevice::ReadOnly);
243 if (format !=
"curveslist/add_curve")
249 while (!stream.atEnd())
252 stream >> curve_name;
253 if (!curve_name.isEmpty())
255 curves.push_back(curve_name);
258 if (curves.size() != 1)
264 event->acceptProposedAction();
267 else if (ev->type() == QEvent::Drop)
269 auto lineEdit = qobject_cast<QLineEdit*>(obj);
278 ui->lineFilename->setText(
"");
279 ui->lineEditReference->setText(
"");
280 ui->timeSlider->setEnabled(
false);
281 ui->timeSlider->setValue(0);
282 ui->decodeButton->setEnabled(
false);
299 QProgressDialog progress_dialog;
300 progress_dialog.setWindowTitle(
"PlotJuggler Video");
301 progress_dialog.setLabelText(
"Decoding file");
302 progress_dialog.setWindowModality(Qt::ApplicationModal);
303 progress_dialog.setRange(0,
_media_player->duration() * fps / 1000);
304 progress_dialog.setAutoClose(
true);
305 progress_dialog.setAutoReset(
true);
306 progress_dialog.show();
313 const QtAV::VideoFrame frame =
_frame_reader->getVideoFrame();
319 QImage image = frame.toImage(QImage::Format_RGB888);
322 compressed_frame.
info.
width = frame.width();
323 compressed_frame.
info.
height = frame.height();
331 if( ++count % 10 == 0 )
333 progress_dialog.setValue(count);
334 QApplication::processEvents();
335 if (progress_dialog.wasCanceled())
347 ui->decodeButton->setEnabled(
false);
void on_loadButton_clicked()
bool loadFile(QString filename)
bool eventFilter(QObject *obj, QEvent *ev)
void on_clearButton_clicked()
void on_timeSlider_valueChanged(int value)
const QPixmap * pixmap() const
std::vector< CompressedFrame > _compressed_frames
ImageLabel(QWidget *parent=nullptr)
const QPixmap & LoadSvg(QString filename, QString style_name="light")
void paintEvent(QPaintEvent *)
VideoDialog(QWidget *parent=nullptr)
QString referenceCurve() const
void * qoi_encode(const void *data, const qoi_desc *desc, int *out_len)
void * qoi_decode(const void *data, int size, qoi_desc *desc, int channels)
std::unique_ptr< QtAV::FrameReader > _frame_reader
constexpr auto count() -> size_t
QtAV::VideoOutput * _video_output
const T & move(const T &v)
void on_decodeButton_clicked()
void setPixmap(const QPixmap &)
QtAV::AVPlayer * _media_player
void seekByValue(double value)
std::basic_string< Char > format(const text_style &ts, const S &format_str, const Args &... args)