Merge branch 'master' into otio
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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,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,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,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,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,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,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,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,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,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,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,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**
|
||||||
|
|||||||
@@ -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.*/
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
# Olive Video Editor [](https://travis-ci.org/olive-editor/olive) [](https://ci.appveyor.com/project/itsmattkc/olive)
|
# Olive Video Editor [](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.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
**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
@@ -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()
|
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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(),
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user