various: allow users to override the start and end index of image sequences

Also includes various fixes to footage property setting/signalling.
This commit is contained in:
itsmattkc
2020-03-09 19:58:42 +11:00
parent 0131d83256
commit 16b072fa98
11 changed files with 181 additions and 26 deletions
@@ -21,7 +21,9 @@
#include "videostreamproperties.h"
#include <QGridLayout>
#include <QGroupBox>
#include <QLabel>
#include <QMessageBox>
#include <OpenColorIO/OpenColorIO.h>
namespace OCIO = OCIO_NAMESPACE::v1;
@@ -35,12 +37,16 @@ VideoStreamProperties::VideoStreamProperties(ImageStreamPtr stream) :
QGridLayout* video_layout = new QGridLayout(this);
video_layout->setMargin(0);
video_layout->addWidget(new QLabel(tr("Color Space:")), 0, 0);
int row = 0;
video_layout->addWidget(new QLabel(tr("Color Space:")), row, 0);
video_color_space_ = new QComboBox();
OCIO::ConstConfigRcPtr config = stream->footage()->project()->color_manager()->GetConfig();
int number_of_colorspaces = config->getNumColorSpaces();
video_color_space_->addItem(tr("Default (%1)").arg(stream->footage()->project()->default_input_colorspace()));
for (int i=0;i<number_of_colorspaces;i++) {
QString colorspace = config->getColorSpaceNameByIndex(i);
@@ -49,22 +55,91 @@ VideoStreamProperties::VideoStreamProperties(ImageStreamPtr stream) :
video_color_space_->setCurrentText(stream_->colorspace());
video_layout->addWidget(video_color_space_, 0, 1);
video_layout->addWidget(video_color_space_, row, 1);
row++;
video_premultiply_alpha_ = new QCheckBox(tr("Premultiplied Alpha"));
video_premultiply_alpha_->setChecked(stream_->premultiplied_alpha());
video_layout->addWidget(video_premultiply_alpha_, 1, 0, 1, 2);
video_layout->addWidget(video_premultiply_alpha_, row, 0, 1, 2);
row++;
if (IsImageSequence(stream.get())) {
QGroupBox* imgseq_group = new QGroupBox(tr("Image Sequence"));
QGridLayout* imgseq_layout = new QGridLayout(imgseq_group);
int imgseq_row = 0;
VideoStream* video_stream = static_cast<VideoStream*>(stream.get());
imgseq_layout->addWidget(new QLabel(tr("Start Index:")), imgseq_row, 0);
imgseq_start_time_ = new IntegerSlider();
imgseq_start_time_->SetMinimum(0);
imgseq_start_time_->SetValue(video_stream->start_time());
imgseq_layout->addWidget(imgseq_start_time_, imgseq_row, 1);
imgseq_row++;
imgseq_layout->addWidget(new QLabel(tr("End Index:")), imgseq_row, 0);
imgseq_end_time_ = new IntegerSlider();
imgseq_end_time_->SetMinimum(0);
imgseq_end_time_->SetValue(video_stream->start_time() + video_stream->duration());
imgseq_layout->addWidget(imgseq_end_time_, imgseq_row, 1);
video_layout->addWidget(imgseq_group, row, 0, 1, 2);
}
}
void VideoStreamProperties::Accept(QUndoCommand *parent)
{
QString set_colorspace;
if (video_color_space_->currentIndex() > 0) {
set_colorspace = video_color_space_->currentText();
}
if (video_premultiply_alpha_->isChecked() != stream_->premultiplied_alpha()
|| video_color_space_->currentText() != stream_->colorspace()) {
|| set_colorspace != stream_->colorspace(false)) {
new VideoStreamChangeCommand(stream_,
video_premultiply_alpha_->isChecked(),
video_color_space_->currentText(),
set_colorspace,
parent);
}
if (IsImageSequence(stream_.get())) {
VideoStreamPtr video_stream = std::static_pointer_cast<VideoStream>(stream_);
if (video_stream->start_time() != imgseq_start_time_->GetValue()) {
new ImageSequenceChangeCommand(video_stream,
imgseq_start_time_->GetValue(),
imgseq_end_time_->GetValue() - imgseq_start_time_->GetValue(),
parent);
}
}
}
bool VideoStreamProperties::SanityCheck()
{
if (IsImageSequence(stream_.get())) {
if (imgseq_start_time_->GetValue() >= imgseq_end_time_->GetValue()) {
QMessageBox::critical(this,
tr("Invalid Configuration"),
tr("Image sequence end index must be a value higher than the start index."),
QMessageBox::Ok);
return false;
}
}
return true;
}
bool VideoStreamProperties::IsImageSequence(ImageStream *stream)
{
return (stream->type() == Stream::kVideo && static_cast<VideoStream*>(stream)->is_image_sequence());
}
VideoStreamProperties::VideoStreamChangeCommand::VideoStreamChangeCommand(ImageStreamPtr stream,
@@ -81,7 +156,7 @@ VideoStreamProperties::VideoStreamChangeCommand::VideoStreamChangeCommand(ImageS
void VideoStreamProperties::VideoStreamChangeCommand::redo_internal()
{
old_premultiplied_ = stream_->premultiplied_alpha();
old_colorspace_ = stream_->colorspace();
old_colorspace_ = stream_->colorspace(false);
stream_->set_premultiplied_alpha(new_premultiplied_);
stream_->set_colorspace(new_colorspace_);
@@ -92,3 +167,26 @@ void VideoStreamProperties::VideoStreamChangeCommand::undo_internal()
stream_->set_premultiplied_alpha(old_premultiplied_);
stream_->set_colorspace(old_colorspace_);
}
VideoStreamProperties::ImageSequenceChangeCommand::ImageSequenceChangeCommand(VideoStreamPtr video_stream, int64_t start_index, int64_t duration, QUndoCommand *parent) :
UndoCommand(parent),
video_stream_(video_stream),
new_start_index_(start_index),
new_duration_(duration)
{
}
void VideoStreamProperties::ImageSequenceChangeCommand::redo_internal()
{
old_start_index_ = video_stream_->start_time();
video_stream_->set_start_time(new_start_index_);
old_duration_ = video_stream_->duration();
video_stream_->set_duration(new_duration_);
}
void VideoStreamProperties::ImageSequenceChangeCommand::undo_internal()
{
video_stream_->set_start_time(old_start_index_);
video_stream_->set_duration(old_duration_);
}
@@ -27,6 +27,7 @@
#include "project/item/footage/videostream.h"
#include "streamproperties.h"
#include "undo/undocommand.h"
#include "widget/slider/integerslider.h"
class VideoStreamProperties : public StreamProperties
{
@@ -35,7 +36,11 @@ public:
virtual void Accept(QUndoCommand* parent) override;
virtual bool SanityCheck() override;
private:
static bool IsImageSequence(ImageStream* stream);
/**
* @brief Attached video stream
*/
@@ -51,6 +56,16 @@ private:
*/
QComboBox* video_color_space_;
/**
* @brief Sets the start index for image sequences
*/
IntegerSlider* imgseq_start_time_;
/**
* @brief Sets the end index for image sequences
*/
IntegerSlider* imgseq_end_time_;
class VideoStreamChangeCommand : public UndoCommand {
public:
VideoStreamChangeCommand(ImageStreamPtr stream,
@@ -70,6 +85,29 @@ private:
bool old_premultiplied_;
QString old_colorspace_;
};
class ImageSequenceChangeCommand : public UndoCommand {
public:
ImageSequenceChangeCommand(VideoStreamPtr video_stream,
int64_t start_index,
int64_t duration,
QUndoCommand* parent = nullptr);
protected:
virtual void redo_internal() override;
virtual void undo_internal() override;
private:
VideoStreamPtr video_stream_;
int64_t new_start_index_;
int64_t old_start_index_;
int64_t new_duration_;
int64_t old_duration_;
};
};
+5 -9
View File
@@ -69,22 +69,18 @@ void MediaInput::FootageChanged()
return;
}
if (connected_footage_ != nullptr) {
if (connected_footage_->type() == Stream::kImage || connected_footage_->type() == Stream::kVideo) {
disconnect(connected_footage_.get(), SIGNAL(ColorSpaceChanged()), this, SLOT(FootageColorSpaceChanged()));
}
if (connected_footage_) {
disconnect(connected_footage_.get(), &Stream::ParametersChanged, this, &MediaInput::FootageParametersChanged);
}
connected_footage_ = new_footage;
if (connected_footage_ != nullptr) {
if (connected_footage_->type() == Stream::kImage || connected_footage_->type() == Stream::kVideo) {
connect(connected_footage_.get(), SIGNAL(ColorSpaceChanged()), this, SLOT(FootageColorSpaceChanged()));
}
if (connected_footage_) {
connect(connected_footage_.get(), &Stream::ParametersChanged, this, &MediaInput::FootageParametersChanged);
}
}
void MediaInput::FootageColorSpaceChanged()
void MediaInput::FootageParametersChanged()
{
InvalidateCache(0, RATIONAL_MAX, footage_input_);
}
+1 -1
View File
@@ -48,7 +48,7 @@ protected:
private slots:
void FootageChanged();
void FootageColorSpaceChanged();
void FootageParametersChanged();
};
+7 -5
View File
@@ -91,11 +91,13 @@ bool ImageStream::premultiplied_alpha() const
void ImageStream::set_premultiplied_alpha(bool e)
{
premultiplied_alpha_ = e;
emit ParametersChanged();
}
const QString &ImageStream::colorspace() const
const QString &ImageStream::colorspace(bool default_if_empty) const
{
if (colorspace_.isEmpty()) {
if (colorspace_.isEmpty() && default_if_empty) {
return footage()->project()->default_input_colorspace();
} else {
return colorspace_;
@@ -106,7 +108,7 @@ void ImageStream::set_colorspace(const QString &color)
{
colorspace_ = color;
emit ColorSpaceChanged();
emit ParametersChanged();
}
void ImageStream::ColorConfigChanged()
@@ -123,13 +125,13 @@ void ImageStream::ColorConfigChanged()
}
// Either way, the color calculation has likely changed so we signal here
emit ColorSpaceChanged();
emit ParametersChanged();
}
void ImageStream::DefaultColorSpaceChanged()
{
// If no colorspace is set, this stream uses the default color space and it's just changed
if (colorspace_.isEmpty()) {
emit ColorSpaceChanged();
emit ParametersChanged();
}
}
+1 -4
View File
@@ -43,12 +43,9 @@ public:
bool premultiplied_alpha() const;
void set_premultiplied_alpha(bool e);
const QString& colorspace() const;
const QString& colorspace(bool default_if_empty = true) const;
void set_colorspace(const QString& color);
signals:
void ColorSpaceChanged();
protected:
virtual void FootageSetEvent(Footage*) override;
+2
View File
@@ -107,6 +107,8 @@ const int64_t &Stream::duration() const
void Stream::set_duration(const int64_t &duration)
{
duration_ = duration;
emit ParametersChanged();
}
bool Stream::enabled() const
+2
View File
@@ -115,6 +115,8 @@ protected:
signals:
void IndexChanged();
void ParametersChanged();
private:
Footage* footage_;
+13 -1
View File
@@ -27,7 +27,8 @@
const int64_t VideoStream::kEndTimestamp = AV_NOPTS_VALUE;
VideoStream::VideoStream() :
start_time_(0)
start_time_(0),
is_image_sequence_(false)
{
set_type(kVideo);
}
@@ -57,6 +58,17 @@ const int64_t &VideoStream::start_time() const
void VideoStream::set_start_time(const int64_t &start_time)
{
start_time_ = start_time;
emit ParametersChanged();
}
bool VideoStream::is_image_sequence() const
{
return is_image_sequence_;
}
void VideoStream::set_image_sequence(bool e)
{
is_image_sequence_ = e;
}
int64_t VideoStream::get_closest_timestamp_in_frame_index(const rational &time)
+6
View File
@@ -25,6 +25,7 @@
class VideoStream : public ImageStream
{
Q_OBJECT
public:
VideoStream();
@@ -43,6 +44,9 @@ public:
const int64_t& start_time() const;
void set_start_time(const int64_t& start_time);
bool is_image_sequence() const;
void set_image_sequence(bool e);
int64_t get_closest_timestamp_in_frame_index(const rational& time);
int64_t get_closest_timestamp_in_frame_index(int64_t timestamp);
void clear_frame_index();
@@ -62,6 +66,8 @@ private:
QMutex index_access_lock_;
bool is_image_sequence_;
};
using VideoStreamPtr = std::shared_ptr<VideoStream>;
+2
View File
@@ -179,6 +179,8 @@ void VideoRenderWorker::HashNodeRecursively(QCryptographicHash *hash, const Node
if (stream->type() == Stream::kVideo) {
hash->addData(QStringLiteral("%1/%2").arg(QString::number(input_time.numerator()),
QString::number(input_time.denominator())).toUtf8());
hash->addData(QString::number(static_cast<VideoStream*>(stream.get())->start_time()).toUtf8());
/*Decoder::RetrieveState state = decoder->GetRetrieveState(input_time);
if (state == Decoder::kReady) {