Merge branch 'master' into otio

This commit is contained in:
itsmattkc
2020-09-22 20:13:58 +10:00
31 changed files with 405 additions and 329 deletions
@@ -5,7 +5,6 @@ title: "[UNSUPPORTED]"
labels: "Legacy (Unsupported)" labels: "Legacy (Unsupported)"
assignees: '' assignees: ''
--- ---
# Olive 0.1 is unsupported # Olive 0.1 is unsupported
Unfortunately no one is supporting Olive 0.1 at this time. Any reports pertaining to it will be Unfortunately no one is supporting Olive 0.1 at this time. Any reports pertaining to it will be
+13 -3
View File
@@ -4,16 +4,26 @@ about: Report a fatal crash that resulted in Olive unexpectedly closing.
title: "[CRASH]" title: "[CRASH]"
labels: "Crash, Triage" labels: "Crash, Triage"
assignees: '' assignees: ''
--- ---
**Commit Hash (8 character string of letters/numbers in title bar)** **Commit Hash** <!-- 8 character string of letters/numbers in title bar (e.g. 3ea173c9) -->
**Platform** **Platform**
**Summary** **Summary**
**Steps to Reproduce** **Steps to Reproduce**
**Backtrace** 1.
2.
3.
<details><summary><strong>Backtrace</strong></summary><pre><code>
<!-- Paste backtrace here -->
</code></pre></details>
**Additional Information** **Additional Information**
+4 -2
View File
@@ -4,12 +4,14 @@ about: Report an issue related to compiling or packaging (including continuous i
title: "[BUILD]" title: "[BUILD]"
labels: "Building/Packaging, Triage" labels: "Building/Packaging, Triage"
assignees: '' assignees: ''
--- ---
**Commit Hash (8 character string of letters/numbers in title bar)** **Commit Hash** <!-- 8 character string of letters/numbers in title bar (e.g. 3ea173c9) -->
**Platform** **Platform**
**Summary** **Summary**
**Additional Information / Output** **Additional Information / Output**
+4 -2
View File
@@ -4,12 +4,14 @@ about: Report an issue related to the disk cache system, including failure to c
title: "[CACHE]" title: "[CACHE]"
labels: "Disk Cache, Triage" labels: "Disk Cache, Triage"
assignees: '' assignees: ''
--- ---
**Commit Hash (8 character string of letters/numbers in title bar)** **Commit Hash** <!-- 8 character string of letters/numbers in title bar (e.g. 3ea173c9) -->
**Platform** **Platform**
**Summary** **Summary**
**Additional Information / Output** **Additional Information / Output**
+4 -2
View File
@@ -4,12 +4,14 @@ about: Report an issue related to codec handling, including importing footage or
title: "[CODEC]" title: "[CODEC]"
labels: "Codec, Triage" labels: "Codec, Triage"
assignees: '' assignees: ''
--- ---
**Commit Hash (8 character string of letters/numbers in title bar)** **Commit Hash** <!-- 8 character string of letters/numbers in title bar (e.g. 3ea173c9) -->
**Platform** **Platform**
**Summary** **Summary**
**Additional Information / Output** **Additional Information / Output**
+4 -2
View File
@@ -4,12 +4,14 @@ about: Report an issue related to the management of pixels and color, including
title: "[COLOR]" title: "[COLOR]"
labels: "Color Management, Triage" labels: "Color Management, Triage"
assignees: '' assignees: ''
--- ---
**Commit Hash (8 character string of letters/numbers in title bar)** **Commit Hash** <!-- 8 character string of letters/numbers in title bar (e.g. 3ea173c9) -->
**Platform** **Platform**
**Summary** **Summary**
**Additional Information / Output** **Additional Information / Output**
+4 -2
View File
@@ -4,12 +4,14 @@ about: Report an issue related to the overall editing experience, including usa
title: "[EDIT]" title: "[EDIT]"
labels: "Timeline/Editing, Triage" labels: "Timeline/Editing, Triage"
assignees: '' assignees: ''
--- ---
**Commit Hash (8 character string of letters/numbers in title bar)** **Commit Hash** <!-- 8 character string of letters/numbers in title bar (e.g. 3ea173c9) -->
**Platform** **Platform**
**Summary** **Summary**
**Additional Information / Output** **Additional Information / Output**
+4 -2
View File
@@ -4,12 +4,14 @@ about: Report an issue related to exporting videos from Olive, including errors
title: "[EXPORT]" title: "[EXPORT]"
labels: "Export, Triage" labels: "Export, Triage"
assignees: '' assignees: ''
--- ---
**Commit Hash (8 character string of letters/numbers in title bar)** **Commit Hash** <!-- 8 character string of letters/numbers in title bar (e.g. 3ea173c9) -->
**Platform** **Platform**
**Summary** **Summary**
**Additional Information / Output** **Additional Information / Output**
+4 -2
View File
@@ -4,12 +4,14 @@ about: Report an issue related to the node-based compositing system, including
title: "[NODES]" title: "[NODES]"
labels: "Nodes/Compositing, Triage" labels: "Nodes/Compositing, Triage"
assignees: '' assignees: ''
--- ---
**Commit Hash (8 character string of letters/numbers in title bar)** **Commit Hash** <!-- 8 character string of letters/numbers in title bar (e.g. 3ea173c9) -->
**Platform** **Platform**
**Summary** **Summary**
**Additional Information / Output** **Additional Information / Output**
+4 -2
View File
@@ -4,12 +4,14 @@ about: Report an issue related to the playback of video or audio, including lag
title: "[PLAYBACK]" title: "[PLAYBACK]"
labels: "Playback, Triage" labels: "Playback, Triage"
assignees: '' assignees: ''
--- ---
**Commit Hash (8 character string of letters/numbers in title bar)** **Commit Hash** <!-- 8 character string of letters/numbers in title bar (e.g. 3ea173c9) -->
**Platform** **Platform**
**Summary** **Summary**
**Additional Information / Output** **Additional Information / Output**
+4 -2
View File
@@ -4,12 +4,14 @@ about: Report an issue related to project management, including working with an
title: "[PROJECT]" title: "[PROJECT]"
labels: "Project, Triage" labels: "Project, Triage"
assignees: '' assignees: ''
--- ---
**Commit Hash (8 character string of letters/numbers in title bar)** **Commit Hash** <!-- 8 character string of letters/numbers in title bar (e.g. 3ea173c9) -->
**Platform** **Platform**
**Summary** **Summary**
**Additional Information / Output** **Additional Information / Output**
+4 -2
View File
@@ -4,12 +4,14 @@ about: Report an issue related to rendering, including corrupted frames, incorr
title: "[RENDER]" title: "[RENDER]"
labels: "Renderer, Triage" labels: "Renderer, Triage"
assignees: '' assignees: ''
--- ---
**Commit Hash (8 character string of letters/numbers in title bar)** **Commit Hash** <!-- 8 character string of letters/numbers in title bar (e.g. 3ea173c9) -->
**Platform** **Platform**
**Summary** **Summary**
**Additional Information / Output** **Additional Information / Output**
+4 -2
View File
@@ -4,12 +4,14 @@ about: Report an issue related to general user interface usability, including b
title: "[UI]" title: "[UI]"
labels: "User Interface, Triage" labels: "User Interface, Triage"
assignees: '' assignees: ''
--- ---
**Commit Hash (8 character string of letters/numbers in title bar)** **Commit Hash** <!-- 8 character string of letters/numbers in title bar (e.g. 3ea173c9) -->
**Platform** **Platform**
**Summary** **Summary**
**Additional Information / Output** **Additional Information / Output**
+7
View File
@@ -139,14 +139,21 @@ jobs:
then then
mkdir olive-editor mkdir olive-editor
cp app/olive-editor.exe olive-editor cp app/olive-editor.exe olive-editor
cp app/olive-crashhandler.exe olive-editor
cp app/olive-editor.pdb olive-editor cp app/olive-editor.pdb olive-editor
windeployqt olive-editor/olive-crashhandler.exe
windeployqt olive-editor/olive-editor.exe windeployqt olive-editor/olive-editor.exe
cp $(cygpath $GITHUB_WORKSPACE)/bin/*.dll olive-editor cp $(cygpath $GITHUB_WORKSPACE)/bin/*.dll olive-editor
cp $(cygpath $GITHUB_WORKSPACE)/out/Default/crashpad_handler.exe olive-editor cp $(cygpath $GITHUB_WORKSPACE)/out/Default/crashpad_handler.exe olive-editor
cp $(cygpath $GITHUB_WORKSPACE)/minidump_stackwalk/* olive-editor
elif [ "$MATRIX_OS" == "macos-latest" ] elif [ "$MATRIX_OS" == "macos-latest" ]
then then
export BUNDLE_NAME=Olive.app export BUNDLE_NAME=Olive.app
mv app/$BUNDLE_NAME . mv app/$BUNDLE_NAME .
# HACK: OCIO doesn't link it's library properly so we need to manually correct
install_name_tool -change libOpenColorIO.1.dylib @rpath/libOpenColorIO.1.dylib $BUNDLE_NAME/Contents/MacOS/Olive
macdeployqt $BUNDLE_NAME macdeployqt $BUNDLE_NAME
$DOWNLOAD_TOOL https://github.com/arl/macdeployqtfix/raw/master/macdeployqtfix.py $DOWNLOAD_TOOL https://github.com/arl/macdeployqtfix/raw/master/macdeployqtfix.py
python2 macdeployqtfix.py $BUNDLE_NAME/Contents/MacOS/Olive /usr/local/Cellar/qt5/5.*/ python2 macdeployqtfix.py $BUNDLE_NAME/Contents/MacOS/Olive /usr/local/Cellar/qt5/5.*/
+2
View File
@@ -29,6 +29,8 @@ set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON) set(CMAKE_AUTORCC ON)
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13")
set(OLIVE_DEFINITIONS -DAPPVERSION="${PROJECT_VERSION}" -DQT_DEPRECATED_WARNINGS) set(OLIVE_DEFINITIONS -DAPPVERSION="${PROJECT_VERSION}" -DQT_DEPRECATED_WARNINGS)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
+7 -9
View File
@@ -1,19 +1,17 @@
# Olive Video Editor [![Build Status](https://travis-ci.org/olive-editor/olive.svg?branch=master)](https://travis-ci.org/olive-editor/olive) [![Build Status](https://ci.appveyor.com/api/projects/status/5s4jabxayg51rv95?svg=true)](https://ci.appveyor.com/project/itsmattkc/olive) # Olive Video Editor [![Build status](https://github.com/olive-editor/olive/workflows/CI/badge.svg?branch=master)](https://github.com/olive-editor/olive/actions?query=branch%3Amaster)
Olive is a free non-linear video editor for Windows, macOS, and Linux. Olive is a free non-linear video editor for Windows, macOS, and Linux.
![screen](https://www.olivevideoeditor.org/img/screenshot.jpg) ![screen](https://olivevideoeditor.org/img/020-2.png)
**Discover more:** [Website](https://www.olivevideoeditor.org/) | [Twitter](https://twitter.com/oliveteam) | [Discord](https://discord.gg/4Ae9KZn) | [Patreon](https://www.patreon.com/olivevideoeditor) **Discover more:** [Website](https://www.olivevideoeditor.org/) | [Binaries](https://olivevideoeditor.org/download.php) | [Twitter](https://twitter.com/oliveteam) | [Discord](https://discord.gg/4Ae9KZn) | [Patreon](https://www.patreon.com/olivevideoeditor) | [Tutorials](https://github.com/olive-editor/olive/wiki/Overview-Guide)
## Getting Started with Olive:
Binaries of Olive are available at: https://olivevideoeditor.org/download.php
Some tutorials can be seen on the GitHub Wiki: https://github.com/olive-editor/olive/wiki/Overview-Guide
**NOTE: Olive is alpha software and is considered highly unstable. While we highly appreciate users testing and providing usage information, please use at your own risk.** **NOTE: Olive is alpha software and is considered highly unstable. While we highly appreciate users testing and providing usage information, please use at your own risk.**
## Binaries
[Nightly binaries are available on the website.](https://olivevideoeditor.org/download.php)
## Support Olive: ## Support Olive:
Please consider supporting Olive: Please consider supporting Olive:
+48 -40
View File
@@ -185,6 +185,54 @@ if (GoogleCrashpad_FOUND)
PRIVATE PRIVATE
${CRASHPAD_LIBRARIES} ${CRASHPAD_LIBRARIES}
) )
set(OLIVE_CRASH_TARGET "olive-crashhandler")
set(OLIVE_CRASH_SOURCES
dialog/crashhandler/crashhandler.h
dialog/crashhandler/crashhandler.cpp
dialog/crashhandler/crashhandlermain.cpp
)
if (WIN32)
add_executable(
${OLIVE_CRASH_TARGET}
WIN32
${OLIVE_CRASH_SOURCES}
)
else()
add_executable(
${OLIVE_CRASH_TARGET}
${OLIVE_CRASH_SOURCES}
)
endif()
target_include_directories(
${OLIVE_CRASH_TARGET}
PRIVATE
${CRASHPAD_INCLUDE_DIRS}
)
target_link_libraries(
${OLIVE_CRASH_TARGET}
PRIVATE
Qt5::Core
Qt5::Gui
Qt5::Widgets
Qt5::Network
${CRASHPAD_LIBRARIES}
)
if(UNIX AND NOT APPLE)
install(TARGETS ${OLIVE_TARGET} ${OLIVE_CRASH_TARGET} RUNTIME DESTINATION bin)
endif()
if(APPLE)
# Move crash handler program inside Mac app bundle
add_custom_command(TARGET ${OLIVE_CRASH_TARGET} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${OLIVE_CRASH_TARGET} $<TARGET_FILE_DIR:${OLIVE_TARGET}>
)
endif()
endif() endif()
# Set compiler definitions # Set compiler definitions
@@ -209,43 +257,3 @@ if(DOXYGEN_FOUND)
set(DOXYGEN_EXTRACT_PRIVATE "YES") set(DOXYGEN_EXTRACT_PRIVATE "YES")
doxygen_add_docs(docs ALL ${OLIVE_SOURCES}) doxygen_add_docs(docs ALL ${OLIVE_SOURCES})
endif() endif()
set(OLIVE_CRASH_TARGET "olive-crashhandler")
set(OLIVE_CRASH_SOURCES
dialog/crashhandler/crashhandler.h
dialog/crashhandler/crashhandler.cpp
dialog/crashhandler/crashhandlermain.cpp
)
if (WIN32)
add_executable(
${OLIVE_CRASH_TARGET}
WIN32
${OLIVE_CRASH_SOURCES}
)
else()
add_executable(
${OLIVE_CRASH_TARGET}
${OLIVE_CRASH_SOURCES}
)
endif()
target_link_libraries(
${OLIVE_CRASH_TARGET}
PRIVATE
Qt5::Core
Qt5::Gui
Qt5::Widgets
)
if(UNIX AND NOT APPLE)
install(TARGETS ${OLIVE_TARGET} ${OLIVE_CRASH_TARGET} RUNTIME DESTINATION bin)
endif()
if(APPLE)
# Move crash handler program inside Mac app bundle
add_custom_command(TARGET ${OLIVE_CRASH_TARGET} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${OLIVE_CRASH_TARGET} $<TARGET_FILE_DIR:${OLIVE_TARGET}>
)
endif()
+27 -2
View File
@@ -68,11 +68,17 @@ bool OIIODecoder::Probe(Footage *f, const QAtomicInt *cancelled)
// Heuristically determine whether this file is part of an image sequence or not // Heuristically determine whether this file is part of an image sequence or not
if (GetImageSequenceDigitCount(f->filename()) > 0) { if (GetImageSequenceDigitCount(f->filename()) > 0) {
QSize dim(in->spec().width, in->spec().height);
int64_t ind = GetImageSequenceIndex(f->filename()); int64_t ind = GetImageSequenceIndex(f->filename());
// Check if files around exist around it with that follow a sequence // Check if files around exist around it with that follow a sequence
if (QFileInfo::exists(TransformImageSequenceFileName(f->filename(), ind - 1)) QString previous_img_fn = TransformImageSequenceFileName(f->filename(), ind - 1);
|| QFileInfo::exists(TransformImageSequenceFileName(f->filename(), ind + 1))) { QString next_img_fn = TransformImageSequenceFileName(f->filename(), ind + 1);
// GetImageDimensions will return a 0,0 size if the file doesn't exist, so it's safe to check
// both existence and matching size with this
if (GetImageDimensions(previous_img_fn) == dim || GetImageDimensions(next_img_fn) == dim) {
// We need user feedback here and since UI must occur in the UI thread (and we could be in any thread), we defer // We need user feedback here and since UI must occur in the UI thread (and we could be in any thread), we defer
// to the Core which will definitely be in the UI thread and block here until we get an answer from the user // to the Core which will definitely be in the UI thread and block here until we get an answer from the user
QMetaObject::invokeMethod(Core::instance(), QMetaObject::invokeMethod(Core::instance(),
@@ -316,6 +322,25 @@ bool OIIODecoder::FileTypeIsSupported(const QString& fn)
return true; return true;
} }
QSize OIIODecoder::GetImageDimensions(const QString &fn)
{
QSize sz;
auto in = OIIO::ImageInput::open(fn.toStdString());
if (in) {
sz.setWidth(in->spec().width);
sz.setHeight(in->spec().height);
in->close();
#if OIIO_VERSION < 10903
OIIO::ImageInput::destroy(in);
#endif
}
return sz;
}
bool OIIODecoder::OpenImageHandler(const QString &fn) bool OIIODecoder::OpenImageHandler(const QString &fn)
{ {
image_ = OIIO::ImageInput::open(fn.toStdString()); image_ = OIIO::ImageInput::open(fn.toStdString());
+2
View File
@@ -68,6 +68,8 @@ private:
static bool FileTypeIsSupported(const QString& fn); static bool FileTypeIsSupported(const QString& fn);
static QSize GetImageDimensions(const QString& fn);
bool OpenImageHandler(const QString& fn); bool OpenImageHandler(const QString& fn);
void CloseImageHandle(); void CloseImageHandle();
+2 -3
View File
@@ -23,10 +23,9 @@ set(OLIVE_SOURCES
common/clamp.h common/clamp.h
common/commandlineparser.h common/commandlineparser.h
common/commandlineparser.cpp common/commandlineparser.cpp
common/crashhandler.h
common/crashhandler.cpp
common/crashpadinterface.cpp
common/crashpadinterface.h common/crashpadinterface.h
common/crashpadinterface.cpp
common/crashpadutils.h
common/debug.h common/debug.h
common/debug.cpp common/debug.cpp
common/define.h common/define.h
-150
View File
@@ -1,150 +0,0 @@
/***
Olive - Non-Linear Video Editor
Copyright (C) 2019 Olive Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#include "crashhandler.h"
#include <QApplication>
#include <QDir>
#include <QFile>
#include <QProcess>
#include <QStandardPaths>
#include <QTextStream>
#include <QtGlobal>
#if defined(Q_OS_WINDOWS)
#include <Windows.h>
#include <DbgHelp.h>
#include <stdio.h>
#include <stdlib.h>
#elif defined(Q_OS_MAC) || defined(Q_OS_LINUX)
#include <execinfo.h>
#endif
#include "common/filefunctions.h"
OLIVE_NAMESPACE_ENTER
void crash_handler(int sig)
{
QString log_path = QDir(FileFunctions::GetTempFilePath()).filePath(QStringLiteral("olive_crash"));
QFile output(log_path);
output.open(QFile::WriteOnly);
QTextStream ostream(&output);
#ifdef GITHASH
ostream << "Version: " << GITHASH << "\n";
#endif
ostream << "Signal: " << sig << "\n\n";
#if defined(Q_OS_WINDOWS)
// Use Windows stackwalk API
HANDLE process = GetCurrentProcess();
HANDLE thread = GetCurrentThread();
CONTEXT context;
memset(&context, 0, sizeof(CONTEXT));
context.ContextFlags = CONTEXT_FULL;
RtlCaptureContext(&context);
SymInitialize(process, NULL, TRUE);
DWORD image;
STACKFRAME64 stackframe;
ZeroMemory(&stackframe, sizeof(STACKFRAME64));
#ifdef _M_IX86
image = IMAGE_FILE_MACHINE_I386;
stackframe.AddrPC.Offset = context.Eip;
stackframe.AddrPC.Mode = AddrModeFlat;
stackframe.AddrFrame.Offset = context.Ebp;
stackframe.AddrFrame.Mode = AddrModeFlat;
stackframe.AddrStack.Offset = context.Esp;
stackframe.AddrStack.Mode = AddrModeFlat;
#elif _M_X64
image = IMAGE_FILE_MACHINE_AMD64;
stackframe.AddrPC.Offset = context.Rip;
stackframe.AddrPC.Mode = AddrModeFlat;
stackframe.AddrFrame.Offset = context.Rsp;
stackframe.AddrFrame.Mode = AddrModeFlat;
stackframe.AddrStack.Offset = context.Rsp;
stackframe.AddrStack.Mode = AddrModeFlat;
#elif _M_IA64
image = IMAGE_FILE_MACHINE_IA64;
stackframe.AddrPC.Offset = context.StIIP;
stackframe.AddrPC.Mode = AddrModeFlat;
stackframe.AddrFrame.Offset = context.IntSp;
stackframe.AddrFrame.Mode = AddrModeFlat;
stackframe.AddrBStore.Offset = context.RsBSP;
stackframe.AddrBStore.Mode = AddrModeFlat;
stackframe.AddrStack.Offset = context.IntSp;
stackframe.AddrStack.Mode = AddrModeFlat;
#endif
for (int i = 0; i < 50; i++) {
BOOL result = StackWalk64(
image, process, thread,
&stackframe, &context, NULL,
SymFunctionTableAccess64, SymGetModuleBase64, NULL);
if (!result) { break; }
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
symbol->MaxNameLen = MAX_SYM_NAME;
DWORD64 displacement = 0;
ostream << "[" << i << "] ";
if (SymFromAddr(process, stackframe.AddrPC.Offset, &displacement, symbol)) {
ostream << symbol->Name;
//printf("[%i] %s\n", i, symbol->Name);
} else {
ostream << "???";
//printf("[%i] ???\n", i);
}
ostream << "\n";
}
SymCleanup(process);
#elif defined(Q_OS_MAC) || defined(Q_OS_LINUX)
void *array[10];
size_t size;
// get void*'s for all entries on the stack
size = backtrace(array, 10);
// print out all the frames to stderr
backtrace_symbols_fd(array, size, output.handle());
#endif
output.close();
QString crash_handler_exe = QDir(qApp->applicationDirPath()).filePath(QStringLiteral("olive-crashhandler"));
QProcess::startDetached(crash_handler_exe, {log_path});
exit(1);
}
OLIVE_NAMESPACE_EXIT
+38 -43
View File
@@ -23,75 +23,67 @@
#ifdef USE_CRASHPAD #ifdef USE_CRASHPAD
#include <QCoreApplication> #include <QCoreApplication>
#include <QDateTime>
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
#include <QMessageBox> #include <QMessageBox>
#include <QProcess>
#include "crashpadutils.h"
#include "filefunctions.h" #include "filefunctions.h"
#ifdef Q_OS_WINDOWS #ifdef OS_WIN
#include <Windows.h> #include <Windows.h>
#endif #endif
// Copied from base::FilePath to match its macro
#if defined(OS_POSIX)
// On most platforms, native pathnames are char arrays, and the encoding
// may or may not be specified. On Mac OS X, native pathnames are encoded
// in UTF-8.
#define TO_BASE_STRING_TYPE(x) x.toStdString()
#elif defined(OS_WIN)
// On Windows, for Unicode-aware applications, native pathnames are wchar_t
// arrays encoded in UTF-16.
#define TO_BASE_STRING_TYPE(x) x.toStdWString()
#endif // OS_WIN
crashpad::CrashpadClient *client; crashpad::CrashpadClient *client;
bool ShowCrashConfirmation() QString GenerateReportPath()
{ {
QString msg = QCoreApplication::translate("CrashReport", return QDir(OLIVE_NAMESPACE::FileFunctions::GetTempFilePath()).filePath(QStringLiteral("reports"));
"We're sorry, Olive has crashed. "
"Would you like to send an error report to "
"help developers fix this issue?\n\n"
"Crash reports are anonymous and only send "
"non-specific details about your computer and"
"how the crash occurred.");
return (QMessageBox::critical(nullptr,
QString(),
msg,
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes);
} }
#ifdef Q_OS_WINDOWS base::FilePath GenerateReportPathForCrashpad()
{
return base::FilePath(QSTRING_TO_BASE_STRING(GenerateReportPath()));
}
#if defined(OS_WIN)
LONG WINAPI Win32ExceptionHandler(_EXCEPTION_POINTERS *ExceptionInfo) LONG WINAPI Win32ExceptionHandler(_EXCEPTION_POINTERS *ExceptionInfo)
{ {
if (ShowCrashConfirmation()) { QString crash_handler_exe = QDir(qApp->applicationDirPath()).filePath(QStringLiteral("olive-crashhandler"));
client->DumpAndCrash(ExceptionInfo); QProcess::startDetached(crash_handler_exe, {GenerateReportPath(), QString::number(QDateTime::currentSecsSinceEpoch())});
}
client->DumpAndCrash(ExceptionInfo);
return EXCEPTION_CONTINUE_SEARCH; return EXCEPTION_CONTINUE_SEARCH;
} }
#elif defined(OS_LINUX)
bool LinuxExceptionHandler(int, siginfo_t*, ucontext_t*)
{
QString crash_handler_exe = QDir(qApp->applicationDirPath()).filePath(QStringLiteral("olive-crashhandler"));
QProcess::startDetached(crash_handler_exe, {GenerateReportPath(), QString::number(QDateTime::currentSecsSinceEpoch())});
// Returning false signals to Crashpad to proceed with its own exception handling
return false;
}
#endif #endif
bool InitializeCrashpad() bool InitializeCrashpad()
{ {
QString exe_dir = QCoreApplication::applicationDirPath(); QString exe_dir = QCoreApplication::applicationDirPath();
#ifdef OS_WIN
base::FilePath handler(QSTRING_TO_BASE_STRING(QDir(exe_dir).filePath(QStringLiteral("crashpad_handler.exe"))));
#else
// FIXME: On Linux, probably should put this in a subdir so that it doesn't conflict with // FIXME: On Linux, probably should put this in a subdir so that it doesn't conflict with
// anything else in /usr/bin // anything else in /usr/bin
base::FilePath handler(QSTRING_TO_BASE_STRING(QDir(exe_dir).filePath(QStringLiteral("crashpad_handler"))));
#ifdef Q_OS_WINDOWS
base::FilePath handler(TO_BASE_STRING_TYPE(QDir(exe_dir).filePath(QStringLiteral("crashpad_handler.exe"))));
#else
base::FilePath handler(TO_BASE_STRING_TYPE(QDir(exe_dir).filePath(QStringLiteral("crashpad_handler"))));
#endif #endif
base::FilePath reports_dir(TO_BASE_STRING_TYPE(QDir(OLIVE_NAMESPACE::FileFunctions::GetTempFilePath()).filePath("reports"))); base::FilePath reports_dir = GenerateReportPathForCrashpad();
base::FilePath metrics_dir(TO_BASE_STRING_TYPE(QDir(OLIVE_NAMESPACE::FileFunctions::GetTempFilePath()).filePath("metrics"))); base::FilePath metrics_dir(QSTRING_TO_BASE_STRING(QDir(OLIVE_NAMESPACE::FileFunctions::GetTempFilePath()).filePath(QStringLiteral("metrics"))));
std::string url = "https://olivevideoeditor.org/crashpad/report.php";
// Metadata that will be posted to the server with the crash report map // Metadata that will be posted to the server with the crash report map
std::map<std::string, std::string> annotations; std::map<std::string, std::string> annotations;
@@ -105,19 +97,22 @@ bool InitializeCrashpad()
std::unique_ptr<crashpad::CrashReportDatabase> database = crashpad::CrashReportDatabase::Initialize(reports_dir); std::unique_ptr<crashpad::CrashReportDatabase> database = crashpad::CrashReportDatabase::Initialize(reports_dir);
if (database == NULL) return false; if (database == NULL) return false;
// Enable automated crash uploads // Disable automated crash uploads
crashpad::Settings *settings = database->GetSettings(); crashpad::Settings *settings = database->GetSettings();
if (settings == NULL) return false; if (settings == NULL) return false;
settings->SetUploadsEnabled(true); settings->SetUploadsEnabled(false);
// Start crash handler // Start crash handler
client = new crashpad::CrashpadClient(); client = new crashpad::CrashpadClient();
bool status = client->StartHandler(handler, reports_dir, metrics_dir, bool status = client->StartHandler(handler, reports_dir, metrics_dir,
url, annotations, arguments, true, true); "https://olivevideoeditor.org/crashpad/report.php",
annotations, arguments, true, true);
// Override Crashpad exception filter with our own // Override Crashpad exception filter with our own
#ifdef Q_OS_WINDOWS #if defined(OS_WIN)
SetUnhandledExceptionFilter(Win32ExceptionHandler); SetUnhandledExceptionFilter(Win32ExceptionHandler);
#elif defined(OS_LINUX)
crashpad::CrashpadClient::SetFirstChanceExceptionHandler(LinuxExceptionHandler);
#endif #endif
return status; return status;
-1
View File
@@ -23,7 +23,6 @@
#ifdef USE_CRASHPAD #ifdef USE_CRASHPAD
#include <client/crashpad_client.h>
#include <client/crash_report_database.h> #include <client/crash_report_database.h>
#include <client/settings.h> #include <client/settings.h>
@@ -18,15 +18,23 @@
***/ ***/
#ifndef CRASHHANDLER_H #ifndef CRASHPADUTILS_H
#define CRASHHANDLER_H #define CRASHPADUTILS_H
#include "common/define.h" #include <client/crashpad_client.h>
OLIVE_NAMESPACE_ENTER // Copied from base::FilePath to match its macro
#if defined(OS_POSIX)
// On most platforms, native pathnames are char arrays, and the encoding
// may or may not be specified. On Mac OS X, native pathnames are encoded
// in UTF-8.
#define QSTRING_TO_BASE_STRING(x) x.toStdString()
#define BASE_STRING_TO_QSTRING(x) QString::fromStdString(x)
#elif defined(OS_WIN)
// On Windows, for Unicode-aware applications, native pathnames are wchar_t
// arrays encoded in UTF-16.
#define QSTRING_TO_BASE_STRING(x) x.toStdWString()
#define BASE_STRING_TO_QSTRING(x) QString::fromStdWString(x)
#endif // OS_WIN
void crash_handler(int sig); #endif // CRASHPADUTILS_H
OLIVE_NAMESPACE_EXIT
#endif // CRASHHANDLER_H
+148 -33
View File
@@ -20,66 +20,181 @@
#include "crashhandler.h" #include "crashhandler.h"
#include <QApplication>
#include <QDir>
#include <QFile> #include <QFile>
#include <QFontDatabase>
#include <QLabel> #include <QLabel>
#include <QDialogButtonBox> #include <QHttpMultiPart>
#include <QMessageBox>
#include <QNetworkAccessManager>
#include <QProcess>
#include <QScrollBar> #include <QScrollBar>
#include <QTextEdit> #include <QThread>
#include <QTimer>
#include <QVBoxLayout> #include <QVBoxLayout>
#include "common/crashpadutils.h"
OLIVE_NAMESPACE_ENTER OLIVE_NAMESPACE_ENTER
CrashHandlerDialog::CrashHandlerDialog(const char *log_file) CrashHandlerDialog::CrashHandlerDialog(const char *report_dir, const char* crash_time)
{ {
setWindowTitle(tr("Olive")); setWindowTitle(tr("Olive"));
crash_time_ = QString(crash_time).toULongLong();
report_dir_ = report_dir;
QVBoxLayout* layout = new QVBoxLayout(this); QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(new QLabel(tr("We're sorry, Olive has crashed. Please send the following log to the developers to " layout->addWidget(new QLabel(tr("We're sorry, Olive has crashed. Please help us fix it by "
"help resolve this."))); "sending an error report.")));
QTextEdit* edit = new QTextEdit(); summary_edit_ = new QTextEdit();
edit->setReadOnly(true); summary_edit_->setPlaceholderText(tr("Describe what you were doing in as much detail as "
layout->addWidget(edit); "possible. If you can, provide steps to reproduce this crash."));
edit->append(QStringLiteral("Build Environment: %1 (%2)").arg(QSysInfo::buildCpuArchitecture(), QSysInfo::buildAbi())); layout->addWidget(summary_edit_);
edit->append(QStringLiteral("Run Environment: %1").arg(QSysInfo::currentCpuArchitecture()));
edit->append(QStringLiteral("Kernel: %1 %2").arg(QSysInfo::kernelType(), QSysInfo::kernelVersion()));
edit->append(QStringLiteral("System: %1 (%2 %3)").arg(QSysInfo::prettyProductName(), QSysInfo::productType(), QSysInfo::productVersion()));
edit->append(QString());
QDialogButtonBox* buttons = new QDialogButtonBox(); layout->addWidget(new QLabel(tr("Crash Report:")));
// FIXME: Implement auto-reporting crash_report_ = new QTextEdit();
//buttons->addButton(tr("Send Error Report"), QDialogButtonBox::AcceptRole); crash_report_->setReadOnly(true);
//buttons->addButton(tr("Don't Send"), QDialogButtonBox::RejectRole); crash_report_->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
buttons->addButton(QDialogButtonBox::Ok); layout->addWidget(crash_report_);
connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept); QHBoxLayout* btn_layout = new QHBoxLayout();
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject); btn_layout->setMargin(0);
layout->addWidget(buttons); btn_layout->addStretch();
QFile log(log_file); send_report_btn_ = new QPushButton(tr("Send Error Report"));
if (log.open(QFile::ReadOnly | QFile::Text)) { connect(send_report_btn_, &QPushButton::clicked, this, &CrashHandlerDialog::SendErrorReport);
edit->append(log.readAll()); btn_layout->addWidget(send_report_btn_);
QMetaObject::invokeMethod(edit->verticalScrollBar(), dont_send_btn_ = new QPushButton(tr("Don't Send"));
"setValue", connect(dont_send_btn_, &QPushButton::clicked, this, &CrashHandlerDialog::reject);
Qt::QueuedConnection, btn_layout->addWidget(dont_send_btn_);
Q_ARG(int, 0));
log.close(); layout->addLayout(btn_layout);
crash_report_->setEnabled(false);
send_report_btn_->setEnabled(false);
crash_report_->setText(tr("Waiting for crash report to be generated..."));
AttemptToFindReport();
}
void CrashHandlerDialog::SetGUIObjectsEnabled(bool e)
{
summary_edit_->setEnabled(e);
crash_report_->setEnabled(e);
send_report_btn_->setEnabled(e);
dont_send_btn_->setEnabled(e);
}
void CrashHandlerDialog::GenerateReport()
{
QProcess* p = new QProcess();
connect(p, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, &CrashHandlerDialog::ReadProcessFinished);
connect(p, &QProcess::readyReadStandardOutput, this, &CrashHandlerDialog::ReadProcessHasData);
QString stackwalk_filename;
#if defined(OS_WIN)
stackwalk_filename = QStringLiteral("minidump_stackwalk.exe");
#else
stackwalk_filename = QStringLiteral("minidump_stackwalk");
#endif
QString stackwalk_bin = QDir(qApp->applicationDirPath()).filePath(stackwalk_filename);
p->start(stackwalk_bin, {report_filename_});
crash_report_->setText(QStringLiteral("Trying to run: %1").arg(stackwalk_bin));
}
void CrashHandlerDialog::ReplyFinished(QNetworkReply* reply)
{
if (reply->error() == QNetworkReply::NoError) {
// Close dialog
QDialog::accept();
} else {
QMessageBox::critical(this, tr("Upload Failed"),
tr("Failed to send error report. Please try again later."),
QMessageBox::Ok);
SetGUIObjectsEnabled(true);
} }
} }
void CrashHandlerDialog::accept() void CrashHandlerDialog::AttemptToFindReport()
{ {
QDialog::accept(); // Retrieve reports from Crashpad database
std::unique_ptr<crashpad::CrashReportDatabase> database = crashpad::CrashReportDatabase::Initialize(base::FilePath(QSTRING_TO_BASE_STRING(QString(report_dir_))));
std::vector<crashpad::CrashReportDatabase::Report> reports;
database->GetCompletedReports(&reports);
// Find report that was made after the crash time
foreach (const crashpad::CrashReportDatabase::Report& report, reports) {
if (report.creation_time >= crash_time_) {
report_filename_ = BASE_STRING_TO_QSTRING(report.file_path.value());
break;
}
}
// If we found it, use it, otherwise wait a second and try again
if (report_filename_.isEmpty()) {
// Couldn't find report, try again in one second
QTimer::singleShot(500, this, &CrashHandlerDialog::AttemptToFindReport);
} else {
GenerateReport();
}
} }
void CrashHandlerDialog::reject() void CrashHandlerDialog::ReadProcessHasData()
{ {
QDialog::reject(); report_data_.append(static_cast<QProcess*>(sender())->readAllStandardOutput());
}
void CrashHandlerDialog::ReadProcessFinished()
{
SetGUIObjectsEnabled(true);
crash_report_->setText(report_data_);
delete sender();
}
void CrashHandlerDialog::SendErrorReport()
{
SetGUIObjectsEnabled(false);
QNetworkAccessManager* manager = new QNetworkAccessManager();
connect(manager, &QNetworkAccessManager::finished, this, &CrashHandlerDialog::ReplyFinished);
QNetworkRequest request;
request.setSslConfiguration(QSslConfiguration::defaultConfiguration());
request.setUrl(QStringLiteral("https://olivevideoeditor.org/crashpad/report.php"));
// Create HTTP form
QHttpMultiPart* multipart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
// Create description section
QHttpPart desc_part;
desc_part.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("text/plain"));
desc_part.setHeader(QNetworkRequest::ContentDispositionHeader, QStringLiteral("form-data; name=\"description\""));
desc_part.setBody(summary_edit_->toPlainText().toUtf8());
multipart->append(desc_part);
// Create file section
QHttpPart file_part;
file_part.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/octet-stream"));
file_part.setHeader(QNetworkRequest::ContentDispositionHeader, QStringLiteral("form-data; name=\"upload_file_minidump\"; filename=\"%1\"")
.arg(QFileInfo(report_filename_).fileName()));
QFile* file = new QFile(report_filename_);
file->open(QFile::ReadOnly);
file_part.setBodyDevice(file);
file->setParent(multipart); // Delete file with multipart
multipart->append(file_part);
manager->post(request, multipart);
} }
OLIVE_NAMESPACE_EXIT OLIVE_NAMESPACE_EXIT
+36 -4
View File
@@ -21,7 +21,12 @@
#ifndef CRASHHANDLERDIALOG_H #ifndef CRASHHANDLERDIALOG_H
#define CRASHHANDLERDIALOG_H #define CRASHHANDLERDIALOG_H
#include <client/crash_report_database.h>
#include <QDialog> #include <QDialog>
#include <QDialogButtonBox>
#include <QNetworkReply>
#include <QPushButton>
#include <QTextEdit>
#include "common/define.h" #include "common/define.h"
@@ -31,12 +36,39 @@ class CrashHandlerDialog : public QDialog
{ {
Q_OBJECT Q_OBJECT
public: public:
CrashHandlerDialog(const char* log_file); CrashHandlerDialog(const char* report_dir, const char* crash_time);
public slots: private:
virtual void accept() override; void SetGUIObjectsEnabled(bool e);
virtual void reject() override; void GenerateReport();
QTextEdit* summary_edit_;
QTextEdit* crash_report_;
QPushButton* send_report_btn_;
QPushButton* dont_send_btn_;
QString report_filename_;
time_t crash_time_;
QString report_dir_;
QByteArray report_data_;
private slots:
void ReplyFinished(QNetworkReply *reply);
void AttemptToFindReport();
void ReadProcessHasData();
void ReadProcessFinished();
void SendErrorReport();
}; };
+2 -2
View File
@@ -24,13 +24,13 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
if (argc < 2) { if (argc < 3) {
return 1; return 1;
} }
QApplication a(argc, argv); QApplication a(argc, argv);
OLIVE_NAMESPACE::CrashHandlerDialog chd(argv[1]); OLIVE_NAMESPACE::CrashHandlerDialog chd(argv[1], argv[2]);
chd.open(); chd.open();
return a.exec(); return a.exec();
+1 -1
View File
@@ -126,7 +126,7 @@ void RenderWorker::RenderFrame(RenderTicketPtr ticket, ViewerOutput* viewer, con
FramePtr frame = Frame::Create(); FramePtr frame = Frame::Create();
frame->set_timestamp(time); frame->set_timestamp(time);
if (video_force_download_resolution_) { if (video_force_download_resolution_ || texture.isNull()) {
// If we're setting the resolution ourselves or we're zeroing it out, allocate the frame now // If we're setting the resolution ourselves or we're zeroing it out, allocate the frame now
frame->set_video_params(VideoParams(video_params_.width(), frame->set_video_params(VideoParams(video_params_.width(),
video_params_.height(), video_params_.height(),
+6 -1
View File
@@ -358,12 +358,17 @@ void FrameHashCache::HashDeleted(const QString& s, const QByteArray &hash)
return; return;
} }
TimeRangeList ranges_to_invalidate;
QMap<rational, QByteArray>::const_iterator i; QMap<rational, QByteArray>::const_iterator i;
for (i=time_hash_map_.constBegin(); i!=time_hash_map_.constEnd(); i++) { for (i=time_hash_map_.constBegin(); i!=time_hash_map_.constEnd(); i++) {
if (i.value() == hash) { if (i.value() == hash) {
Invalidate(TimeRange(i.key(), i.key() + timebase_)); ranges_to_invalidate.InsertTimeRange(TimeRange(i.key(), i.key() + timebase_));
} }
} }
foreach (const TimeRange& range, ranges_to_invalidate) {
Invalidate(range);
}
} }
void FrameHashCache::ProjectInvalidated(Project *p) void FrameHashCache::ProjectInvalidated(Project *p)
+1 -5
View File
@@ -99,11 +99,7 @@ void ViewerDisplayWidget::SetSignalCursorColorEnabled(bool e)
void ViewerDisplayWidget::SetImage(FramePtr in_buffer) void ViewerDisplayWidget::SetImage(FramePtr in_buffer)
{ {
if (in_buffer && in_buffer->is_allocated()) { last_loaded_buffer_ = in_buffer;
last_loaded_buffer_ = in_buffer;
} else {
last_loaded_buffer_ = nullptr;
}
if (last_loaded_buffer_) { if (last_loaded_buffer_) {
makeCurrent(); makeCurrent();
+4
View File
@@ -79,6 +79,10 @@ foreach (COMPONENT ${_crashpad_components})
list(APPEND CRASHPAD_LIBRARIES ${CRASHPAD_${UPPERCOMPONENT}_LIB}) list(APPEND CRASHPAD_LIBRARIES ${CRASHPAD_${UPPERCOMPONENT}_LIB})
endforeach() endforeach()
if (UNIX AND NOT APPLE)
list(APPEND CRASHPAD_LIBRARIES ${CMAKE_DL_LIBS} Threads::Threads)
endif()
find_package_handle_standard_args(GoogleCrashpad find_package_handle_standard_args(GoogleCrashpad
REQUIRED_VARS REQUIRED_VARS
CRASHPAD_LIBRARIES CRASHPAD_LIBRARIES