From 0e2632e578dc29cacf884f8d233eda83083da703 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 5 Dec 2018 22:34:53 +1100 Subject: [PATCH] added export ETA --- dialogs/exportdialog.cpp | 13 ++++++++++--- dialogs/exportdialog.h | 2 +- dialogs/exportdialog.ui | 7 +++++-- io/exportthread.cpp | 26 ++++++++++++++++++++------ io/exportthread.h | 2 +- 5 files changed, 37 insertions(+), 13 deletions(-) diff --git a/dialogs/exportdialog.cpp b/dialogs/exportdialog.cpp index ca5a8a52a..0ff349cc1 100644 --- a/dialogs/exportdialog.cpp +++ b/dialogs/exportdialog.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "debug.h" #include "panels/panels.h" @@ -474,7 +475,7 @@ void ExportDialog::on_pushButton_clicked() { connect(et, SIGNAL(finished()), et, SLOT(deleteLater())); connect(et, SIGNAL(finished()), this, SLOT(render_thread_finished())); - connect(et, SIGNAL(progress_changed(int)), this, SLOT(update_progress_bar(int))); + connect(et, SIGNAL(progress_changed(int, qint64)), this, SLOT(update_progress_bar(int, qint64))); closeActiveClips(sequence, true); @@ -517,8 +518,14 @@ void ExportDialog::on_pushButton_clicked() { } } -void ExportDialog::update_progress_bar(int value) { - ui->progressBar->setValue(value); +void ExportDialog::update_progress_bar(int value, qint64 remaining_ms) { + // convert ms to H:MM:SS + int seconds = qFloor(remaining_ms*0.001)%60; + int minutes = qFloor(remaining_ms/60000)%60; + int hours = qFloor(remaining_ms/3600000); + ui->progressBar->setFormat("%p% (ETA: " + QString::number(hours) + ":" + QString::number(minutes).rightJustified(2, '0') + ":" + QString::number(seconds).rightJustified(2, '0') + ")"); + + ui->progressBar->setValue(value); } void ExportDialog::on_renderCancel_clicked() { diff --git a/dialogs/exportdialog.h b/dialogs/exportdialog.h index 7505d1b1a..07585b6f9 100644 --- a/dialogs/exportdialog.h +++ b/dialogs/exportdialog.h @@ -25,7 +25,7 @@ private slots: void on_pushButton_clicked(); - void update_progress_bar(int value); + void update_progress_bar(int value, qint64 remaining_ms); void on_renderCancel_clicked(); diff --git a/dialogs/exportdialog.ui b/dialogs/exportdialog.ui index 3133f2766..4a9207014 100644 --- a/dialogs/exportdialog.ui +++ b/dialogs/exportdialog.ui @@ -6,8 +6,8 @@ 0 0 - 358 - 470 + 443 + 562 @@ -227,6 +227,9 @@ 0 + + %p% (ETA: 0:00:00) + diff --git a/io/exportthread.cpp b/io/exportthread.cpp index 8482db33f..320543529 100644 --- a/io/exportthread.cpp +++ b/io/exportthread.cpp @@ -125,6 +125,7 @@ bool ExportThread::setupVideo() { itoa(vcodec_ctx, buffer, 10);*/ //av_opt_set(vcodec_ctx->priv_data, "preset", "fast", AV_OPT_SEARCH_CHILDREN); + av_opt_set(vcodec_ctx->priv_data, "x264opts", "opencl", AV_OPT_SEARCH_CHILDREN); switch (video_compression_type) { case COMPRESSION_TYPE_CFR: @@ -344,8 +345,12 @@ void ExportThread::run() { panel_sequence_viewer->viewer_widget->default_fbo = &fbo; long file_audio_samples = 0; + qint64 start_time, frame_time, avg_time, eta, total_time = 0; + long remaining_frames, frame_count = 1; while (sequence->playhead < end_frame && continueEncode) { + start_time = QDateTime::currentMSecsSinceEpoch(); + panel_sequence_viewer->viewer_widget->paintGL(); double timecode_secs = (double) (sequence->playhead-start_frame) / sequence->frame_rate; @@ -357,10 +362,8 @@ void ExportThread::run() { sws_scale(sws_ctx, video_frame->data, video_frame->linesize, 0, video_frame->height, sws_frame->data, sws_frame->linesize); sws_frame->pts = round(timecode_secs/av_q2d(video_stream->time_base)); - // send to encoder -// dout << "starting encode of video frame" << sequence->playhead; - if (!encode(fmt_ctx, vcodec_ctx, sws_frame, &video_pkt, video_stream)) continueEncode = false; -// dout << "completed encode of video frame" << sequence->playhead; + // send to encoder + if (!encode(fmt_ctx, vcodec_ctx, sws_frame, &video_pkt, video_stream)) continueEncode = false; } if (audio_enabled) { // do we need to encode more audio samples? @@ -389,8 +392,19 @@ void ExportThread::run() { file_audio_samples += swr_frame->nb_samples; } } - emit progress_changed(((double) (sequence->playhead-start_frame) / (double) (end_frame-start_frame)) * 100); + + // encoding stats + frame_time = (QDateTime::currentMSecsSinceEpoch()-start_time); + total_time += frame_time; + remaining_frames = (end_frame-sequence->playhead); + avg_time = (total_time/frame_count); + eta = (remaining_frames*avg_time); + +// dout << "[INFO] Encoded frame" << sequence->playhead << "- took" << frame_time << "ms (avg:" << avg_time << "ms, remaining:" << remaining_frames << ", ETA:" << eta << ")"; + + emit progress_changed(qRound(((double) (sequence->playhead-start_frame) / (double) (end_frame-start_frame)) * 100), eta); sequence->playhead++; + frame_count++; } panel_sequence_viewer->viewer_widget->default_fbo = NULL; @@ -425,7 +439,7 @@ void ExportThread::run() { continueEncode = false; } - emit progress_changed(100); + emit progress_changed(100, 0); } avio_closep(&fmt_ctx->pb); diff --git a/io/exportthread.h b/io/exportthread.h index cd36fc7a9..dfc48c442 100644 --- a/io/exportthread.h +++ b/io/exportthread.h @@ -44,7 +44,7 @@ public: bool continueEncode; signals: - void progress_changed(int value); + void progress_changed(int value, qint64 remaining_ms); private: bool encode(AVFormatContext* ofmt_ctx, AVCodecContext* codec_ctx, AVFrame* frame, AVPacket* packet, AVStream* stream); bool setupVideo();