plug export into render thread

This commit is contained in:
itsmattkc
2019-01-17 01:31:08 +11:00
parent 0580fce981
commit 6a98e33959
6 changed files with 48 additions and 17 deletions
+19 -10
View File
@@ -6,6 +6,7 @@
#include "panels/timeline.h"
#include "panels/viewer.h"
#include "ui/viewerwidget.h"
#include "ui/renderthread.h"
#include "playback/playback.h"
#include "playback/audio.h"
#include "dialogs/exportdialog.h"
@@ -335,23 +336,24 @@ void ExportThread::run() {
}
}
QOpenGLFramebufferObject fbo(sequence->width, sequence->height, QOpenGLFramebufferObject::CombinedDepthStencil, GL_TEXTURE_RECTANGLE);
fbo.bind();
long file_audio_samples = 0;
qint64 start_time, frame_time, avg_time, eta, total_time = 0;
long remaining_frames, frame_count = 1;
RenderThread* renderer = panel_sequence_viewer->viewer_widget->get_renderer();
disconnect(renderer, SIGNAL(ready()), panel_sequence_viewer->viewer_widget, SLOT(queue_repaint()));
connect(renderer, SIGNAL(ready()), this, SLOT(wake()));
mutex.lock();
while (sequence->playhead <= end_frame && continueEncode) {
start_time = QDateTime::currentMSecsSinceEpoch();
panel_sequence_viewer->viewer_widget->paintGL();
renderer->start_render(nullptr, sequence, nullptr, video_frame->data[0]);
waitCond.wait(&mutex);
double timecode_secs = (double) (sequence->playhead-start_frame) / sequence->frame_rate;
if (video_enabled) {
// get image from opengl
glReadPixels(0, 0, video_frame->linesize[0]/4, sequence->height, GL_RGBA, GL_UNSIGNED_BYTE, video_frame->data[0]);
// change pixel format
sws_scale(sws_ctx, video_frame->data, video_frame->linesize, 0, video_frame->height, sws_frame->data, sws_frame->linesize);
sws_frame->pts = qRound(timecode_secs/av_q2d(video_stream->time_base));
@@ -396,11 +398,16 @@ void ExportThread::run() {
// qInfo() << "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);
emit progress_changed(qRound((double(sequence->playhead-start_frame) / double(end_frame-start_frame)) * 100.0), eta);
sequence->playhead++;
frame_count++;
}
disconnect(renderer, SIGNAL(ready()), this, SLOT(wake()));
connect(renderer, SIGNAL(ready()), panel_sequence_viewer->viewer_widget, SLOT(queue_repaint()));
mutex.unlock();
if (continueEncode) {
if (video_enabled) vpkt_alloc = true;
if (audio_enabled) apkt_alloc = true;
@@ -408,8 +415,6 @@ void ExportThread::run() {
mainWindow->set_rendering_state(false);
fbo.release();
if (audio_enabled && continueEncode) {
// flush swresample
do {
@@ -469,3 +474,7 @@ void ExportThread::run() {
delete [] c_filename;
}
void ExportThread::wake() {
waitCond.wakeAll();
}
+12 -5
View File
@@ -3,6 +3,8 @@
#include <QThread>
#include <QOffscreenSurface>
#include <QMutex>
#include <QWaitCondition>
class ExportDialog;
struct AVFormatContext;
@@ -52,19 +54,21 @@ public:
bool continueEncode;
signals:
void progress_changed(int value, qint64 remaining_ms);
private slots:
void wake();
private:
bool encode(AVFormatContext* ofmt_ctx, AVCodecContext* codec_ctx, AVFrame* frame, AVPacket* packet, AVStream* stream, bool rescale);
bool setupVideo();
bool setupAudio();
bool setupContainer();
AVFormatContext* fmt_ctx;
AVFormatContext* fmt_ctx;
AVStream* video_stream;
AVCodec* vcodec;
AVCodecContext* vcodec_ctx;
AVFrame* video_frame;
AVFrame* sws_frame;
SwsContext* sws_ctx;
SwsContext* sws_ctx;
AVStream* audio_stream;
AVCodec* acodec;
AVFrame* audio_frame;
@@ -72,14 +76,17 @@ private:
AVCodecContext* acodec_ctx;
AVPacket video_pkt;
AVPacket audio_pkt;
SwrContext* swr_ctx;
SwrContext* swr_ctx;
bool vpkt_alloc;
bool apkt_alloc;
bool vpkt_alloc;
bool apkt_alloc;
int aframe_bytes;
int ret;
char* c_filename;
QMutex mutex;
QWaitCondition waitCond;
};
#endif // EXPORTTHREAD_H
+10 -1
View File
@@ -125,12 +125,19 @@ void RenderThread::paint() {
}
}
if (pixel_buffer != nullptr) {
ctx->functions()->glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBuffer);
glReadPixels(0, 0, tex_width, tex_height, GL_RGBA, GL_UNSIGNED_BYTE, pixel_buffer);
ctx->functions()->glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
pixel_buffer = nullptr;
}
glDisable(GL_DEPTH);
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
}
void RenderThread::start_render(QOpenGLContext *share, Sequence *s, const QString& save, int idivider) {
void RenderThread::start_render(QOpenGLContext *share, Sequence *s, const QString& save, GLvoid* pixels, int idivider) {
seq = s;
// stall any dependent actions
@@ -147,6 +154,8 @@ void RenderThread::start_render(QOpenGLContext *share, Sequence *s, const QStrin
}
save_fn = save;
pixel_buffer = pixels;
queued = true;
waitCond.wakeAll();
}
+2 -1
View File
@@ -20,7 +20,7 @@ public:
GLuint frameBuffer;
GLuint texColorBuffer;
void paint();
void start_render(QOpenGLContext* share, Sequence* s, const QString &save = nullptr, int idivider = 0);
void start_render(QOpenGLContext* share, Sequence* s, const QString &save = nullptr, GLvoid *pixels = nullptr, int idivider = 0);
bool did_texture_fail();
void cancel();
signals:
@@ -43,6 +43,7 @@ private:
bool texture_failed;
bool running;
QString save_fn;
GLvoid *pixel_buffer;
};
#endif // RENDERTHREAD_H
+4
View File
@@ -229,6 +229,10 @@ void ViewerWidget::frame_update() {
}
}
RenderThread *ViewerWidget::get_renderer() {
return renderer;
}
//void ViewerWidget::resizeGL(int w, int h)
//{
//}
+1
View File
@@ -44,6 +44,7 @@ public:
bool force_quit;
void frame_update();
RenderThread* get_renderer();
public slots:
void set_waveform_scroll(int s);
protected: