plug export into render thread
This commit is contained in:
+19
-10
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -229,6 +229,10 @@ void ViewerWidget::frame_update() {
|
||||
}
|
||||
}
|
||||
|
||||
RenderThread *ViewerWidget::get_renderer() {
|
||||
return renderer;
|
||||
}
|
||||
|
||||
//void ViewerWidget::resizeGL(int w, int h)
|
||||
//{
|
||||
//}
|
||||
|
||||
@@ -44,6 +44,7 @@ public:
|
||||
bool force_quit;
|
||||
|
||||
void frame_update();
|
||||
RenderThread* get_renderer();
|
||||
public slots:
|
||||
void set_waveform_scroll(int s);
|
||||
protected:
|
||||
|
||||
Reference in New Issue
Block a user