fixed playback/export flickering and hanging

This commit is contained in:
itsmattkc
2018-10-29 17:01:52 +11:00
parent 2e2846597e
commit a54fee767d
32 changed files with 216 additions and 163 deletions
+4 -3
View File
@@ -3,7 +3,8 @@
#include <QFile>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include <QDebug>
#include "debug.h"
Config config;
@@ -90,7 +91,7 @@ void Config::load(QString path) {
}
}
if (stream.hasError()) {
qDebug() << "[ERROR] Error parsing config XML." << stream.errorString();
dout << "[ERROR] Error parsing config XML." << stream.errorString();
}
f.close();
@@ -100,7 +101,7 @@ void Config::load(QString path) {
void Config::save(QString path) {
QFile f(path);
if (!f.open(QIODevice::WriteOnly)) {
qDebug() << "[ERROR] Could not save configuration";
dout << "[ERROR] Could not save configuration";
return;
}
+19 -19
View File
@@ -9,6 +9,7 @@
#include "playback/playback.h"
#include "playback/audio.h"
#include "dialogs/exportdialog.h"
#include "debug.h"
extern "C" {
#include <libavcodec/avcodec.h>
@@ -18,7 +19,6 @@ extern "C" {
#include <libswscale/swscale.h>
}
#include <QDebug>
#include <QApplication>
#include <QOffscreenSurface>
#include <QOpenGLFramebufferObject>
@@ -51,7 +51,7 @@ ExportThread::ExportThread() : continueEncode(true) {
bool ExportThread::encode(AVFormatContext* ofmt_ctx, AVCodecContext* codec_ctx, AVFrame* frame, AVPacket* packet, AVStream* stream) {
ret = avcodec_send_frame(codec_ctx, frame);
if (ret < 0) {
qDebug() << "[ERROR] Failed to send frame to encoder." << ret;
dout << "[ERROR] Failed to send frame to encoder." << ret;
ed->export_error = "failed to send frame to encoder (" + QString::number(ret) + ")";
return false;
}
@@ -62,7 +62,7 @@ bool ExportThread::encode(AVFormatContext* ofmt_ctx, AVCodecContext* codec_ctx,
return true;
} else if (ret < 0) {
if (ret != AVERROR_EOF) {
qDebug() << "[ERROR] Failed to receive packet from encoder." << ret;
dout << "[ERROR] Failed to receive packet from encoder." << ret;
ed->export_error = "failed to receive packet from encoder (" + QString::number(ret) + ")";
}
return false;
@@ -82,7 +82,7 @@ bool ExportThread::setupVideo() {
// find video encoder
vcodec = avcodec_find_encoder((enum AVCodecID) video_codec);
if (!vcodec) {
qDebug() << "[ERROR] Could not find video encoder";
dout << "[ERROR] Could not find video encoder";
ed->export_error = "could not video encoder for " + QString::number(video_codec);
return false;
}
@@ -91,7 +91,7 @@ bool ExportThread::setupVideo() {
video_stream = avformat_new_stream(fmt_ctx, vcodec);
video_stream->id = 0;
if (!video_stream) {
qDebug() << "[ERROR] Could not allocate video stream";
dout << "[ERROR] Could not allocate video stream";
ed->export_error = "could not allocate video stream";
return false;
}
@@ -100,7 +100,7 @@ bool ExportThread::setupVideo() {
vcodec_ctx = video_stream->codec;
// vcodec_ctx = avcodec_alloc_context3(vcodec);
if (!vcodec_ctx) {
qDebug() << "[ERROR] Could not allocate video encoding context";
dout << "[ERROR] Could not allocate video encoding context";
ed->export_error = "could not allocate video encoding context";
return false;
}
@@ -135,7 +135,7 @@ bool ExportThread::setupVideo() {
ret = avcodec_open2(vcodec_ctx, vcodec, NULL);
if (ret < 0) {
qDebug() << "[ERROR] Could not open output video encoder." << ret;
dout << "[ERROR] Could not open output video encoder." << ret;
ed->export_error = "could not open output video encoder (" + QString::number(ret) + ")";
return false;
}
@@ -143,7 +143,7 @@ bool ExportThread::setupVideo() {
// copy video encoder parameters to output stream
ret = avcodec_parameters_from_context(video_stream->codecpar, vcodec_ctx);
if (ret < 0) {
qDebug() << "[ERROR] Could not copy video encoder parameters to output stream." << ret;
dout << "[ERROR] Could not copy video encoder parameters to output stream." << ret;
ed->export_error = "could not copy video encoder parameters to output stream (" + QString::number(ret) + ")";
return false;
}
@@ -187,7 +187,7 @@ bool ExportThread::setupAudio() {
// find encoder
acodec = avcodec_find_encoder(static_cast<AVCodecID>(audio_codec));
if (!acodec) {
qDebug() << "[ERROR] Could not find audio encoder";
dout << "[ERROR] Could not find audio encoder";
ed->export_error = "could not audio encoder for " + QString::number(audio_codec);
return false;
}
@@ -196,7 +196,7 @@ bool ExportThread::setupAudio() {
audio_stream = avformat_new_stream(fmt_ctx, acodec);
audio_stream->id = 1;
if (!audio_stream) {
qDebug() << "[ERROR] Could not allocate audio stream";
dout << "[ERROR] Could not allocate audio stream";
ed->export_error = "could not allocate audio stream";
return false;
}
@@ -205,7 +205,7 @@ bool ExportThread::setupAudio() {
acodec_ctx = audio_stream->codec;
// acodec_ctx = avcodec_alloc_context3(acodec);
if (!acodec_ctx) {
qDebug() << "[ERROR] Could not find allocate audio encoding context";
dout << "[ERROR] Could not find allocate audio encoding context";
ed->export_error = "could not allocate audio encoding context";
return false;
}
@@ -229,7 +229,7 @@ bool ExportThread::setupAudio() {
// open encoder
ret = avcodec_open2(acodec_ctx, acodec, NULL);
if (ret < 0) {
qDebug() << "[ERROR] Could not open output audio encoder." << ret;
dout << "[ERROR] Could not open output audio encoder." << ret;
ed->export_error = "could not open output audio encoder (" + QString::number(ret) + ")";
return false;
}
@@ -237,7 +237,7 @@ bool ExportThread::setupAudio() {
// copy params to output stream
ret = avcodec_parameters_from_context(audio_stream->codecpar, acodec_ctx);
if (ret < 0) {
qDebug() << "[ERROR] Could not copy audio encoder parameters to output stream." << ret;
dout << "[ERROR] Could not copy audio encoder parameters to output stream." << ret;
ed->export_error = "could not copy audio encoder parameters to output stream (" + QString::number(ret) + ")";
return false;
}
@@ -267,7 +267,7 @@ bool ExportThread::setupAudio() {
av_frame_make_writable(audio_frame);
ret = av_frame_get_buffer(audio_frame, 0);
if (ret < 0) {
qDebug() << "[ERROR] Could not allocate audio buffer." << ret;
dout << "[ERROR] Could not allocate audio buffer." << ret;
ed->export_error = "could not allocate audio buffer (" + QString::number(ret) + ")";
return false;
}
@@ -289,7 +289,7 @@ bool ExportThread::setupAudio() {
bool ExportThread::setupContainer() {
avformat_alloc_output_context2(&fmt_ctx, NULL, NULL, c_filename);
if (!fmt_ctx) {
qDebug() << "[ERROR] Could not create output context";
dout << "[ERROR] Could not create output context";
ed->export_error = "could not create output format context";
return false;
}
@@ -298,7 +298,7 @@ bool ExportThread::setupContainer() {
ret = avio_open(&fmt_ctx->pb, c_filename, AVIO_FLAG_WRITE);
if (ret < 0) {
qDebug() << "[ERROR] Could not open output file." << ret;
dout << "[ERROR] Could not open output file." << ret;
ed->export_error = "could not open output file (" + QString::number(ret) + ")";
return false;
}
@@ -310,7 +310,7 @@ void ExportThread::run() {
panel_sequence_viewer->pause();
if (!panel_sequence_viewer->viewer_widget->context()->makeCurrent(&surface)) {
qDebug() << "[ERROR] Make current failed";
dout << "[ERROR] Make current failed";
ed->export_error = "could not make OpenGL context current";
return;
}
@@ -329,7 +329,7 @@ void ExportThread::run() {
if (continueEncode) {
ret = avformat_write_header(fmt_ctx, NULL);
if (ret < 0) {
qDebug() << "[ERROR] Could not write output file header." << ret;
dout << "[ERROR] Could not write output file header." << ret;
ed->export_error = "could not write output file header (" + QString::number(ret) + ")";
continueEncode = false;
}
@@ -418,7 +418,7 @@ void ExportThread::run() {
ret = av_write_trailer(fmt_ctx);
if (ret < 0) {
qDebug() << "[ERROR] Could not write output file trailer." << ret;
dout << "[ERROR] Could not write output file trailer." << ret;
ed->export_error = "could not write output file trailer (" + QString::number(ret) + ")";
continueEncode = false;
}
+17 -14
View File
@@ -5,10 +5,10 @@
#include "panels/project.h"
#include "io/config.h"
#include "io/crc32.h"
#include "debug.h"
#include <QPainter>
#include <QPixmap>
#include <QDebug>
#include <QtMath>
#include <QTreeWidgetItem>
#include <QSemaphore>
@@ -52,7 +52,7 @@ void PreviewGenerator::parse_media() {
for (int i=0;i<(int)fmt_ctx->nb_streams;i++) {
// Find the decoder for the video stream
if (avcodec_find_decoder(fmt_ctx->streams[i]->codecpar->codec_id) == NULL) {
qDebug() << "[ERROR] Unsupported codec in stream" << i << "of file" << media->name;
dout << "[ERROR] Unsupported codec in stream" << i << "of file" << media->name;
} else {
MediaStream* ms = media->get_stream_from_file_index(fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO, i);
bool append = false;
@@ -66,11 +66,11 @@ void PreviewGenerator::parse_media() {
&& fmt_ctx->streams[i]->codecpar->width > 0
&& fmt_ctx->streams[i]->codecpar->height > 0) {
/*qDebug() << "avg_frame_rate was:" << fmt_ctx->streams[i]->avg_frame_rate.num << "/" << fmt_ctx->streams[i]->avg_frame_rate.den;
qDebug() << "r_frame_rate was:" << fmt_ctx->streams[i]->r_frame_rate.num << "/" << fmt_ctx->streams[i]->r_frame_rate.den;
qDebug() << "codec_frame_rate was:" << fmt_ctx->streams[i]->codec->framerate.num << "/" << fmt_ctx->streams[i]->codec->framerate.den;
qDebug() << "nb_frames was:" << fmt_ctx->streams[i]->nb_frames;
qDebug() << "duration was:" << fmt_ctx->streams[i]->duration << "OR fmt_ctx's duration is:" << fmt_ctx->duration;*/
/*dout << "avg_frame_rate was:" << fmt_ctx->streams[i]->avg_frame_rate.num << "/" << fmt_ctx->streams[i]->avg_frame_rate.den;
dout << "r_frame_rate was:" << fmt_ctx->streams[i]->r_frame_rate.num << "/" << fmt_ctx->streams[i]->r_frame_rate.den;
dout << "codec_frame_rate was:" << fmt_ctx->streams[i]->codec->framerate.num << "/" << fmt_ctx->streams[i]->codec->framerate.den;
dout << "nb_frames was:" << fmt_ctx->streams[i]->nb_frames;
dout << "duration was:" << fmt_ctx->streams[i]->duration << "OR fmt_ctx's duration is:" << fmt_ctx->duration;*/
if (fmt_ctx->streams[i]->avg_frame_rate.den == 0
&& fmt_ctx->streams[i]->duration == AV_NOPTS_VALUE) { // source is LIKELY a still image
@@ -87,8 +87,11 @@ void PreviewGenerator::parse_media() {
}
ms->video_width = fmt_ctx->streams[i]->codecpar->width;
ms->video_height = fmt_ctx->streams[i]->codecpar->height;
// default value, we get the true value later in generate_waveform()
ms->video_auto_interlacing = VIDEO_PROGRESSIVE;
ms->video_interlacing = VIDEO_PROGRESSIVE; // default value, we get the true value later in generate_waveform()
ms->video_interlacing = VIDEO_PROGRESSIVE;
if (append) media->video_tracks.append(ms);
} else if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
ms->audio_channels = fmt_ctx->streams[i]->codecpar->channels;
@@ -122,7 +125,7 @@ bool PreviewGenerator::retrieve_preview(const QString& hash) {
QString thumb_path = get_thumbnail_path(hash, ms);
QFile f(thumb_path);
if (f.exists()) {
qDebug() << "loaded thumb" << ms->file_index << "from" << thumb_path;
dout << "loaded thumb" << ms->file_index << "from" << thumb_path;
ms->video_preview.load(thumb_path);
ms->preview_done = true;
} else {
@@ -135,7 +138,7 @@ bool PreviewGenerator::retrieve_preview(const QString& hash) {
QString waveform_path = get_waveform_path(hash, ms);
QFile f(waveform_path);
if (f.exists()) {
qDebug() << "loaded wave" << ms->file_index << "from" << waveform_path;
dout << "loaded wave" << ms->file_index << "from" << waveform_path;
f.open(QFile::ReadOnly);
QByteArray data = f.readAll();
ms->audio_preview.resize(data.size());
@@ -213,13 +216,13 @@ void PreviewGenerator::generate_waveform() {
int read_ret = av_read_frame(fmt_ctx, &packet);
if (read_ret < 0) {
end_of_file = true;
if (read_ret != AVERROR_EOF) qDebug() << "[ERROR] Failed to read packet for preview generation" << read_ret;
if (read_ret != AVERROR_EOF) dout << "[ERROR] Failed to read packet for preview generation" << read_ret;
break;
}
if (codec_ctx[packet.stream_index] != NULL) {
int send_ret = avcodec_send_packet(codec_ctx[packet.stream_index], &packet);
if (send_ret < 0 && send_ret != AVERROR(EAGAIN)) {
qDebug() << "[ERROR] Failed to send packet for preview generation - aborting" << send_ret;
dout << "[ERROR] Failed to send packet for preview generation - aborting" << send_ret;
end_of_file = true;
break;
}
@@ -419,7 +422,7 @@ void PreviewGenerator::run() {
for (int i=0;i<media->video_tracks.size();i++) {
MediaStream* ms = media->video_tracks.at(i);
if (ms->video_preview.save(get_thumbnail_path(hash, ms), "PNG")) {
qDebug() << "saved" << ms->file_index << "thumb to" << get_thumbnail_path(hash, ms);
dout << "saved" << ms->file_index << "thumb to" << get_thumbnail_path(hash, ms);
}
}
for (int i=0;i<media->audio_tracks.size();i++) {
@@ -428,7 +431,7 @@ void PreviewGenerator::run() {
f.open(QFile::WriteOnly);
f.write(ms->audio_preview.constData(), ms->audio_preview.size());
f.close();
qDebug() << "saved" << ms->file_index << "waveform to" << get_waveform_path(hash, ms);
dout << "saved" << ms->file_index << "waveform to" << get_waveform_path(hash, ms);
}
}