@@ -477,14 +477,19 @@ bool FFmpegDecoder::Probe(Footage *f, const QAtomicInt* cancelled)
|
|||||||
// Retrieve metadata about the media
|
// Retrieve metadata about the media
|
||||||
avformat_find_stream_info(fmt_ctx, nullptr);
|
avformat_find_stream_info(fmt_ctx, nullptr);
|
||||||
|
|
||||||
|
QVector<StreamPtr> streams(fmt_ctx->nb_streams);
|
||||||
|
|
||||||
// Dump it into the Footage object
|
// Dump it into the Footage object
|
||||||
for (unsigned int i=0;i<fmt_ctx->nb_streams;i++) {
|
for (unsigned int i=0;i<fmt_ctx->nb_streams;i++) {
|
||||||
|
|
||||||
AVStream* avstream = fmt_ctx->streams[i];
|
AVStream* avstream = fmt_ctx->streams[i];
|
||||||
|
|
||||||
|
// Find decoder for this stream, if it exists we can proceed
|
||||||
|
AVCodec* decoder = avcodec_find_decoder(avstream->codecpar->codec_id);
|
||||||
|
|
||||||
StreamPtr str;
|
StreamPtr str;
|
||||||
|
|
||||||
if (avstream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
|
if (avstream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && decoder) {
|
||||||
|
|
||||||
bool image_is_still = false;
|
bool image_is_still = false;
|
||||||
rational pixel_aspect_ratio;
|
rational pixel_aspect_ratio;
|
||||||
@@ -564,7 +569,7 @@ bool FFmpegDecoder::Probe(Footage *f, const QAtomicInt* cancelled)
|
|||||||
|
|
||||||
str = image_stream;
|
str = image_stream;
|
||||||
|
|
||||||
} else if (avstream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
|
} else if (avstream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && decoder) {
|
||||||
|
|
||||||
// Create an audio stream object
|
// Create an audio stream object
|
||||||
AudioStreamPtr audio_stream = std::make_shared<AudioStream>();
|
AudioStreamPtr audio_stream = std::make_shared<AudioStream>();
|
||||||
@@ -600,7 +605,7 @@ bool FFmpegDecoder::Probe(Footage *f, const QAtomicInt* cancelled)
|
|||||||
str->set_type(Stream::kAttachment);
|
str->set_type(Stream::kAttachment);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// We should never realistically get here, but we make an "invalid" stream just in case
|
// Fallback to an unknown stream
|
||||||
str->set_type(Stream::kUnknown);
|
str->set_type(Stream::kUnknown);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -611,11 +616,27 @@ bool FFmpegDecoder::Probe(Footage *f, const QAtomicInt* cancelled)
|
|||||||
str->set_timebase(avstream->time_base);
|
str->set_timebase(avstream->time_base);
|
||||||
str->set_duration(avstream->duration);
|
str->set_duration(avstream->duration);
|
||||||
|
|
||||||
f->add_stream(str);
|
streams[i] = str;
|
||||||
}
|
}
|
||||||
|
|
||||||
// As long as we can open the container and retrieve information, this was a successful probe
|
// Check if we could pick up any streams in this file
|
||||||
result = true;
|
bool found_valid_streams = false;
|
||||||
|
|
||||||
|
foreach (StreamPtr stream, streams) {
|
||||||
|
if (stream->type() != Stream::kUnknown) {
|
||||||
|
found_valid_streams = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found_valid_streams) {
|
||||||
|
// Copy streams over
|
||||||
|
foreach (StreamPtr stream, streams) {
|
||||||
|
f->add_stream(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free all memory
|
// Free all memory
|
||||||
@@ -1330,6 +1351,7 @@ void FFmpegDecoderInstance::RemoveFirstFrame()
|
|||||||
|
|
||||||
FFmpegDecoderInstance::FFmpegDecoderInstance(const char *filename, int stream_index) :
|
FFmpegDecoderInstance::FFmpegDecoderInstance(const char *filename, int stream_index) :
|
||||||
fmt_ctx_(nullptr),
|
fmt_ctx_(nullptr),
|
||||||
|
codec_ctx_(nullptr),
|
||||||
opts_(nullptr),
|
opts_(nullptr),
|
||||||
scale_ctx_(nullptr),
|
scale_ctx_(nullptr),
|
||||||
scale_divider_(0),
|
scale_divider_(0),
|
||||||
|
|||||||
+9
-1
@@ -51,6 +51,7 @@
|
|||||||
#include "render/pixelformat.h"
|
#include "render/pixelformat.h"
|
||||||
#include "render/shaderinfo.h"
|
#include "render/shaderinfo.h"
|
||||||
#include "task/project/import/import.h"
|
#include "task/project/import/import.h"
|
||||||
|
#include "task/project/import/importerrordialog.h"
|
||||||
#include "task/project/load/load.h"
|
#include "task/project/load/load.h"
|
||||||
#include "task/project/save/save.h"
|
#include "task/project/save/save.h"
|
||||||
#include "task/taskmanager.h"
|
#include "task/taskmanager.h"
|
||||||
@@ -473,7 +474,14 @@ void Core::AddOpenProjectFromTask(Task *task)
|
|||||||
|
|
||||||
void Core::ImportTaskComplete(Task* task)
|
void Core::ImportTaskComplete(Task* task)
|
||||||
{
|
{
|
||||||
QUndoCommand *command = static_cast<ProjectImportTask*>(task)->GetCommand();
|
ProjectImportTask* import_task = static_cast<ProjectImportTask*>(task);
|
||||||
|
|
||||||
|
QUndoCommand *command = import_task->GetCommand();
|
||||||
|
|
||||||
|
if (import_task->HasInvalidFiles()) {
|
||||||
|
ProjectImportErrorDialog d(import_task->GetInvalidFiles(), main_window_);
|
||||||
|
d.exec();
|
||||||
|
}
|
||||||
|
|
||||||
undo_stack_.pushIfHasChildren(command);
|
undo_stack_.pushIfHasChildren(command);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,5 +18,7 @@ set(OLIVE_SOURCES
|
|||||||
${OLIVE_SOURCES}
|
${OLIVE_SOURCES}
|
||||||
task/project/import/import.h
|
task/project/import/import.h
|
||||||
task/project/import/import.cpp
|
task/project/import/import.cpp
|
||||||
|
task/project/import/importerrordialog.h
|
||||||
|
task/project/import/importerrordialog.cpp
|
||||||
PARENT_SCOPE
|
PARENT_SCOPE
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -122,7 +122,10 @@ void ProjectImportTask::Import(Folder *folder, const QFileInfoList &import, int
|
|||||||
|
|
||||||
f->set_project(nullptr);
|
f->set_project(nullptr);
|
||||||
|
|
||||||
if (f->status() != Footage::kInvalid) {
|
if (f->status() == Footage::kInvalid) {
|
||||||
|
// Add to list so we can tell the user about it later
|
||||||
|
invalid_files_.append(file_info.absoluteFilePath());
|
||||||
|
} else {
|
||||||
// Create undoable command that adds the items to the model
|
// Create undoable command that adds the items to the model
|
||||||
new ProjectViewModel::AddItemCommand(model_,
|
new ProjectViewModel::AddItemCommand(model_,
|
||||||
folder,
|
folder,
|
||||||
|
|||||||
@@ -42,6 +42,16 @@ public:
|
|||||||
return command_;
|
return command_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QStringList& GetInvalidFiles() const
|
||||||
|
{
|
||||||
|
return invalid_files_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasInvalidFiles() const
|
||||||
|
{
|
||||||
|
return !invalid_files_.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool Run() override;
|
virtual bool Run() override;
|
||||||
|
|
||||||
@@ -58,6 +68,8 @@ private:
|
|||||||
|
|
||||||
int file_count_;
|
int file_count_;
|
||||||
|
|
||||||
|
QStringList invalid_files_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
OLIVE_NAMESPACE_EXIT
|
OLIVE_NAMESPACE_EXIT
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/***
|
||||||
|
|
||||||
|
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 "importerrordialog.h"
|
||||||
|
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QListWidget>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
OLIVE_NAMESPACE_ENTER
|
||||||
|
|
||||||
|
ProjectImportErrorDialog::ProjectImportErrorDialog(const QStringList& filenames, QWidget* parent) :
|
||||||
|
QDialog(parent)
|
||||||
|
{
|
||||||
|
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||||
|
|
||||||
|
setWindowTitle(tr("Import Error"));
|
||||||
|
|
||||||
|
layout->addWidget(new QLabel(tr("The following files failed to import. Olive likely does not "
|
||||||
|
"support their formats.")));
|
||||||
|
|
||||||
|
QListWidget* list_widget = new QListWidget();
|
||||||
|
foreach (const QString& s, filenames) {
|
||||||
|
list_widget->addItem(s);
|
||||||
|
}
|
||||||
|
layout->addWidget(list_widget);
|
||||||
|
|
||||||
|
QDialogButtonBox* buttons = new QDialogButtonBox();
|
||||||
|
buttons->setStandardButtons(QDialogButtonBox::Ok);
|
||||||
|
buttons->setCenterButtons(true);
|
||||||
|
connect(buttons, &QDialogButtonBox::accepted, this, &ProjectImportErrorDialog::accept);
|
||||||
|
layout->addWidget(buttons);
|
||||||
|
}
|
||||||
|
|
||||||
|
OLIVE_NAMESPACE_EXIT
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/***
|
||||||
|
|
||||||
|
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/>.
|
||||||
|
|
||||||
|
***/
|
||||||
|
|
||||||
|
#ifndef PROJECTIMPORTERRORDIALOG_H
|
||||||
|
#define PROJECTIMPORTERRORDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
#include "common/define.h"
|
||||||
|
|
||||||
|
OLIVE_NAMESPACE_ENTER
|
||||||
|
|
||||||
|
class ProjectImportErrorDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ProjectImportErrorDialog(const QStringList& filenames, QWidget* parent = nullptr);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
OLIVE_NAMESPACE_EXIT
|
||||||
|
|
||||||
|
#endif // PROJECTIMPORTERRORDIALOG_H
|
||||||
Reference in New Issue
Block a user