fix no video shown
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QOpenGLExtraFunctions>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include "config/config.h"
|
||||
|
||||
@@ -834,28 +835,65 @@ void OpenGLRenderer::ClearDestinationInternal(double r, double g, double b,
|
||||
|
||||
GLuint OpenGLRenderer::CompileShader(GLenum type, const QString &code)
|
||||
{
|
||||
static const QString shader_preamble =
|
||||
const bool is_gles = context_ && context_->isOpenGLES();
|
||||
const int major = context_ ? context_->format().majorVersion() : 0;
|
||||
const int minor = context_ ? context_->format().minorVersion() : 0;
|
||||
const bool is_gles2 = is_gles && (major < 3);
|
||||
const QString gles_preamble = is_gles2
|
||||
? QStringLiteral("#version 100\n\n"
|
||||
"precision highp float;\n\n"
|
||||
"#define frag_color gl_FragColor\n")
|
||||
: QStringLiteral("#version 300 es\n\n"
|
||||
"precision highp float;\n\n");
|
||||
const QString desktop_preamble =
|
||||
// Use appropriate GL 3.2 shader header
|
||||
QStringLiteral("#version 150\n\n"
|
||||
"precision highp float;\n\n");
|
||||
const QString shader_preamble = is_gles ? gles_preamble : desktop_preamble;
|
||||
|
||||
QString complete_code;
|
||||
|
||||
if (!code.startsWith(QStringLiteral("#version"))) {
|
||||
complete_code = shader_preamble;
|
||||
}
|
||||
|
||||
if (code.isEmpty()) {
|
||||
QString base_code = code;
|
||||
if (base_code.isEmpty()) {
|
||||
// Use default code
|
||||
if (type == GL_FRAGMENT_SHADER) {
|
||||
complete_code.append(FileFunctions::ReadFileAsString(
|
||||
QStringLiteral(":/shaders/default.frag")));
|
||||
base_code = FileFunctions::ReadFileAsString(
|
||||
QStringLiteral(":/shaders/default.frag"));
|
||||
} else if (type == GL_VERTEX_SHADER) {
|
||||
complete_code.append(FileFunctions::ReadFileAsString(
|
||||
QStringLiteral(":/shaders/default.vert")));
|
||||
base_code = FileFunctions::ReadFileAsString(
|
||||
QStringLiteral(":/shaders/default.vert"));
|
||||
}
|
||||
}
|
||||
|
||||
QString complete_code;
|
||||
if (base_code.startsWith(QStringLiteral("#version"))) {
|
||||
if (is_gles || !desktop_preamble.startsWith(QStringLiteral("#version"))) {
|
||||
int newline = base_code.indexOf('\n');
|
||||
if (newline >= 0) {
|
||||
complete_code = shader_preamble + base_code.mid(newline + 1);
|
||||
} else {
|
||||
complete_code = shader_preamble;
|
||||
}
|
||||
} else {
|
||||
complete_code = base_code;
|
||||
}
|
||||
} else {
|
||||
complete_code.append(code);
|
||||
complete_code = shader_preamble + base_code;
|
||||
}
|
||||
|
||||
if (is_gles2) {
|
||||
if (type == GL_VERTEX_SHADER) {
|
||||
complete_code.replace(QRegularExpression(QStringLiteral("\\bin\\b")),
|
||||
QStringLiteral("attribute"));
|
||||
complete_code.replace(QRegularExpression(QStringLiteral("\\bout\\b")),
|
||||
QStringLiteral("varying"));
|
||||
} else if (type == GL_FRAGMENT_SHADER) {
|
||||
complete_code.replace(QRegularExpression(QStringLiteral("\\bin\\b")),
|
||||
QStringLiteral("varying"));
|
||||
complete_code.replace(QRegularExpression(
|
||||
QStringLiteral("\\bout\\s+vec4\\s+frag_color\\s*;")),
|
||||
QStringLiteral("// frag_color output"));
|
||||
complete_code.replace(QRegularExpression(QStringLiteral("\\btexture\\b")),
|
||||
QStringLiteral("texture2D"));
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray code_utf8 = complete_code.toUtf8();
|
||||
|
||||
@@ -78,7 +78,7 @@ void TimeBasedWidget::SetScaleAndCenterOnPlayhead(const double &scale)
|
||||
|
||||
ViewerOutput *TimeBasedWidget::GetConnectedNode() const
|
||||
{
|
||||
return viewer_node_;
|
||||
return viewer_node_.data();
|
||||
}
|
||||
|
||||
void TimeBasedWidget::ConnectViewerNode(ViewerOutput *node)
|
||||
@@ -89,10 +89,17 @@ void TimeBasedWidget::ConnectViewerNode(ViewerOutput *node)
|
||||
}
|
||||
|
||||
// Set viewer node
|
||||
ViewerOutput *old = viewer_node_;
|
||||
ViewerOutput *old = viewer_node_.data();
|
||||
viewer_node_ = node;
|
||||
Current::getInstance().setCurrentVideoParams(viewer_node_->GetVideoParams());
|
||||
Current::getInstance().setCurrentAudioParams(viewer_node_->GetAudioParams());
|
||||
if (viewer_node_) {
|
||||
Current::getInstance().setCurrentVideoParams(
|
||||
viewer_node_->GetVideoParams());
|
||||
Current::getInstance().setCurrentAudioParams(
|
||||
viewer_node_->GetAudioParams());
|
||||
} else {
|
||||
Current::getInstance().setCurrentVideoParams(VideoParams());
|
||||
Current::getInstance().setCurrentAudioParams(AudioParams());
|
||||
}
|
||||
if (old) {
|
||||
// Call potential derivative functions for disconnecting the viewer node
|
||||
DisconnectNodeEvent(old);
|
||||
@@ -121,17 +128,17 @@ void TimeBasedWidget::ConnectViewerNode(ViewerOutput *node)
|
||||
|
||||
// Call derivatives
|
||||
for (TimeBasedView *view : timeline_views_) {
|
||||
view->SetViewerNode(viewer_node_);
|
||||
view->SetViewerNode(viewer_node_.data());
|
||||
}
|
||||
ConnectedNodeChangeEvent(viewer_node_);
|
||||
ConnectedNodeChangeEvent(viewer_node_.data());
|
||||
|
||||
if (viewer_node_) {
|
||||
// Connect length changed signal
|
||||
connect(viewer_node_, &ViewerOutput::LengthChanged, this,
|
||||
connect(viewer_node_.data(), &ViewerOutput::LengthChanged, this,
|
||||
&TimeBasedWidget::UpdateMaximumScroll);
|
||||
connect(viewer_node_, &ViewerOutput::RemovedFromGraph, this,
|
||||
connect(viewer_node_.data(), &ViewerOutput::RemovedFromGraph, this,
|
||||
&TimeBasedWidget::ConnectedNodeRemovedFromGraph);
|
||||
connect(viewer_node_, &ViewerOutput::PlayheadChanged, this,
|
||||
connect(viewer_node_.data(), &ViewerOutput::PlayheadChanged, this,
|
||||
&TimeBasedWidget::PlayheadTimeChanged);
|
||||
|
||||
// Connect ruler and scrollbar to timeline points
|
||||
@@ -141,14 +148,14 @@ void TimeBasedWidget::ConnectViewerNode(ViewerOutput *node)
|
||||
// If we're setting the timebase, set it automatically based on the video and audio parameters
|
||||
if (auto_set_timebase_) {
|
||||
AutoUpdateTimebase();
|
||||
connect(viewer_node_, &ViewerOutput::FrameRateChanged, this,
|
||||
connect(viewer_node_.data(), &ViewerOutput::FrameRateChanged, this,
|
||||
&TimeBasedWidget::AutoUpdateTimebase);
|
||||
connect(viewer_node_, &ViewerOutput::SampleRateChanged, this,
|
||||
connect(viewer_node_.data(), &ViewerOutput::SampleRateChanged, this,
|
||||
&TimeBasedWidget::AutoUpdateTimebase);
|
||||
}
|
||||
|
||||
// Call derivatives
|
||||
ConnectNodeEvent(viewer_node_);
|
||||
ConnectNodeEvent(viewer_node_.data());
|
||||
}
|
||||
|
||||
UpdateMaximumScroll();
|
||||
@@ -271,6 +278,10 @@ void TimeBasedWidget::SendCatchUpScrollEvent()
|
||||
|
||||
void TimeBasedWidget::AutoUpdateTimebase()
|
||||
{
|
||||
if (!viewer_node_) {
|
||||
SetTimebase(rational());
|
||||
return;
|
||||
}
|
||||
rational video_tb =
|
||||
viewer_node_->GetVideoParams().frame_rate_as_time_base();
|
||||
|
||||
@@ -448,7 +459,7 @@ void TimeBasedWidget::ZoomOut()
|
||||
void TimeBasedWidget::GoToPrevCut()
|
||||
{
|
||||
// Cuts are only possible in sequences
|
||||
Sequence *sequence = dynamic_cast<Sequence *>(viewer_node_);
|
||||
Sequence *sequence = dynamic_cast<Sequence *>(viewer_node_.data());
|
||||
|
||||
if (!sequence) {
|
||||
return;
|
||||
@@ -480,7 +491,7 @@ void TimeBasedWidget::GoToPrevCut()
|
||||
void TimeBasedWidget::GoToNextCut()
|
||||
{
|
||||
// Cuts are only possible in sequences
|
||||
Sequence *sequence = dynamic_cast<Sequence *>(viewer_node_);
|
||||
Sequence *sequence = dynamic_cast<Sequence *>(viewer_node_.data());
|
||||
|
||||
if (!sequence) {
|
||||
return;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#ifndef TIMEBASEDWIDGET_H
|
||||
#define TIMEBASEDWIDGET_H
|
||||
|
||||
#include <QPointer>
|
||||
#include <QWidget>
|
||||
|
||||
#include "node/output/viewer/viewer.h"
|
||||
@@ -239,7 +240,7 @@ private:
|
||||
|
||||
bool UserIsDraggingPlayhead() const;
|
||||
|
||||
ViewerOutput *viewer_node_;
|
||||
QPointer<ViewerOutput> viewer_node_;
|
||||
|
||||
TimeRuler *ruler_;
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ add_executable(olive-gtest
|
||||
task_taskmanager_test.cpp
|
||||
module_smoke_test.cpp
|
||||
shader_resources_test.cpp
|
||||
timebased_widget_test.cpp
|
||||
timeline_coordinate_test.cpp
|
||||
timeline_workarea_test.cpp
|
||||
)
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "widget/timebased/timebasedwidget.h"
|
||||
#include "node/output/viewer/viewer.h"
|
||||
|
||||
TEST(TimeBasedWidget, ConnectViewerNodeNullSafe)
|
||||
{
|
||||
olive::TimeBasedWidget widget(false, false);
|
||||
widget.ConnectViewerNode(nullptr);
|
||||
EXPECT_EQ(widget.GetConnectedNode(), nullptr);
|
||||
}
|
||||
|
||||
TEST(TimeBasedWidget, ConnectedNodeClearsOnDelete)
|
||||
{
|
||||
olive::TimeBasedWidget widget(false, false);
|
||||
auto *viewer = new olive::ViewerOutput();
|
||||
widget.ConnectViewerNode(viewer);
|
||||
EXPECT_EQ(widget.GetConnectedNode(), viewer);
|
||||
delete viewer;
|
||||
EXPECT_EQ(widget.GetConnectedNode(), nullptr);
|
||||
}
|
||||
Reference in New Issue
Block a user