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:
@@ -21,7 +21,9 @@
|
|||||||
#include "videostreamproperties.h"
|
#include "videostreamproperties.h"
|
||||||
|
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
|
#include <QGroupBox>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
#include <QMessageBox>
|
||||||
#include <OpenColorIO/OpenColorIO.h>
|
#include <OpenColorIO/OpenColorIO.h>
|
||||||
namespace OCIO = OCIO_NAMESPACE::v1;
|
namespace OCIO = OCIO_NAMESPACE::v1;
|
||||||
|
|
||||||
@@ -35,12 +37,16 @@ VideoStreamProperties::VideoStreamProperties(ImageStreamPtr stream) :
|
|||||||
QGridLayout* video_layout = new QGridLayout(this);
|
QGridLayout* video_layout = new QGridLayout(this);
|
||||||
video_layout->setMargin(0);
|
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();
|
video_color_space_ = new QComboBox();
|
||||||
OCIO::ConstConfigRcPtr config = stream->footage()->project()->color_manager()->GetConfig();
|
OCIO::ConstConfigRcPtr config = stream->footage()->project()->color_manager()->GetConfig();
|
||||||
int number_of_colorspaces = config->getNumColorSpaces();
|
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++) {
|
for (int i=0;i<number_of_colorspaces;i++) {
|
||||||
QString colorspace = config->getColorSpaceNameByIndex(i);
|
QString colorspace = config->getColorSpaceNameByIndex(i);
|
||||||
|
|
||||||
@@ -49,22 +55,91 @@ VideoStreamProperties::VideoStreamProperties(ImageStreamPtr stream) :
|
|||||||
|
|
||||||
video_color_space_->setCurrentText(stream_->colorspace());
|
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_ = new QCheckBox(tr("Premultiplied Alpha"));
|
||||||
video_premultiply_alpha_->setChecked(stream_->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)
|
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()
|
if (video_premultiply_alpha_->isChecked() != stream_->premultiplied_alpha()
|
||||||
|| video_color_space_->currentText() != stream_->colorspace()) {
|
|| set_colorspace != stream_->colorspace(false)) {
|
||||||
|
|
||||||
new VideoStreamChangeCommand(stream_,
|
new VideoStreamChangeCommand(stream_,
|
||||||
video_premultiply_alpha_->isChecked(),
|
video_premultiply_alpha_->isChecked(),
|
||||||
video_color_space_->currentText(),
|
set_colorspace,
|
||||||
parent);
|
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,
|
VideoStreamProperties::VideoStreamChangeCommand::VideoStreamChangeCommand(ImageStreamPtr stream,
|
||||||
@@ -81,7 +156,7 @@ VideoStreamProperties::VideoStreamChangeCommand::VideoStreamChangeCommand(ImageS
|
|||||||
void VideoStreamProperties::VideoStreamChangeCommand::redo_internal()
|
void VideoStreamProperties::VideoStreamChangeCommand::redo_internal()
|
||||||
{
|
{
|
||||||
old_premultiplied_ = stream_->premultiplied_alpha();
|
old_premultiplied_ = stream_->premultiplied_alpha();
|
||||||
old_colorspace_ = stream_->colorspace();
|
old_colorspace_ = stream_->colorspace(false);
|
||||||
|
|
||||||
stream_->set_premultiplied_alpha(new_premultiplied_);
|
stream_->set_premultiplied_alpha(new_premultiplied_);
|
||||||
stream_->set_colorspace(new_colorspace_);
|
stream_->set_colorspace(new_colorspace_);
|
||||||
@@ -92,3 +167,26 @@ void VideoStreamProperties::VideoStreamChangeCommand::undo_internal()
|
|||||||
stream_->set_premultiplied_alpha(old_premultiplied_);
|
stream_->set_premultiplied_alpha(old_premultiplied_);
|
||||||
stream_->set_colorspace(old_colorspace_);
|
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 "project/item/footage/videostream.h"
|
||||||
#include "streamproperties.h"
|
#include "streamproperties.h"
|
||||||
#include "undo/undocommand.h"
|
#include "undo/undocommand.h"
|
||||||
|
#include "widget/slider/integerslider.h"
|
||||||
|
|
||||||
class VideoStreamProperties : public StreamProperties
|
class VideoStreamProperties : public StreamProperties
|
||||||
{
|
{
|
||||||
@@ -35,7 +36,11 @@ public:
|
|||||||
|
|
||||||
virtual void Accept(QUndoCommand* parent) override;
|
virtual void Accept(QUndoCommand* parent) override;
|
||||||
|
|
||||||
|
virtual bool SanityCheck() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static bool IsImageSequence(ImageStream* stream);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Attached video stream
|
* @brief Attached video stream
|
||||||
*/
|
*/
|
||||||
@@ -51,6 +56,16 @@ private:
|
|||||||
*/
|
*/
|
||||||
QComboBox* video_color_space_;
|
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 {
|
class VideoStreamChangeCommand : public UndoCommand {
|
||||||
public:
|
public:
|
||||||
VideoStreamChangeCommand(ImageStreamPtr stream,
|
VideoStreamChangeCommand(ImageStreamPtr stream,
|
||||||
@@ -70,6 +85,29 @@ private:
|
|||||||
|
|
||||||
bool old_premultiplied_;
|
bool old_premultiplied_;
|
||||||
QString old_colorspace_;
|
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_;
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -69,22 +69,18 @@ void MediaInput::FootageChanged()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connected_footage_ != nullptr) {
|
if (connected_footage_) {
|
||||||
if (connected_footage_->type() == Stream::kImage || connected_footage_->type() == Stream::kVideo) {
|
disconnect(connected_footage_.get(), &Stream::ParametersChanged, this, &MediaInput::FootageParametersChanged);
|
||||||
disconnect(connected_footage_.get(), SIGNAL(ColorSpaceChanged()), this, SLOT(FootageColorSpaceChanged()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
connected_footage_ = new_footage;
|
connected_footage_ = new_footage;
|
||||||
|
|
||||||
if (connected_footage_ != nullptr) {
|
if (connected_footage_) {
|
||||||
if (connected_footage_->type() == Stream::kImage || connected_footage_->type() == Stream::kVideo) {
|
connect(connected_footage_.get(), &Stream::ParametersChanged, this, &MediaInput::FootageParametersChanged);
|
||||||
connect(connected_footage_.get(), SIGNAL(ColorSpaceChanged()), this, SLOT(FootageColorSpaceChanged()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaInput::FootageColorSpaceChanged()
|
void MediaInput::FootageParametersChanged()
|
||||||
{
|
{
|
||||||
InvalidateCache(0, RATIONAL_MAX, footage_input_);
|
InvalidateCache(0, RATIONAL_MAX, footage_input_);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ protected:
|
|||||||
private slots:
|
private slots:
|
||||||
void FootageChanged();
|
void FootageChanged();
|
||||||
|
|
||||||
void FootageColorSpaceChanged();
|
void FootageParametersChanged();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -91,11 +91,13 @@ bool ImageStream::premultiplied_alpha() const
|
|||||||
void ImageStream::set_premultiplied_alpha(bool e)
|
void ImageStream::set_premultiplied_alpha(bool e)
|
||||||
{
|
{
|
||||||
premultiplied_alpha_ = 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();
|
return footage()->project()->default_input_colorspace();
|
||||||
} else {
|
} else {
|
||||||
return colorspace_;
|
return colorspace_;
|
||||||
@@ -106,7 +108,7 @@ void ImageStream::set_colorspace(const QString &color)
|
|||||||
{
|
{
|
||||||
colorspace_ = color;
|
colorspace_ = color;
|
||||||
|
|
||||||
emit ColorSpaceChanged();
|
emit ParametersChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageStream::ColorConfigChanged()
|
void ImageStream::ColorConfigChanged()
|
||||||
@@ -123,13 +125,13 @@ void ImageStream::ColorConfigChanged()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Either way, the color calculation has likely changed so we signal here
|
// Either way, the color calculation has likely changed so we signal here
|
||||||
emit ColorSpaceChanged();
|
emit ParametersChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageStream::DefaultColorSpaceChanged()
|
void ImageStream::DefaultColorSpaceChanged()
|
||||||
{
|
{
|
||||||
// If no colorspace is set, this stream uses the default color space and it's just changed
|
// If no colorspace is set, this stream uses the default color space and it's just changed
|
||||||
if (colorspace_.isEmpty()) {
|
if (colorspace_.isEmpty()) {
|
||||||
emit ColorSpaceChanged();
|
emit ParametersChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,12 +43,9 @@ public:
|
|||||||
bool premultiplied_alpha() const;
|
bool premultiplied_alpha() const;
|
||||||
void set_premultiplied_alpha(bool e);
|
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);
|
void set_colorspace(const QString& color);
|
||||||
|
|
||||||
signals:
|
|
||||||
void ColorSpaceChanged();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void FootageSetEvent(Footage*) override;
|
virtual void FootageSetEvent(Footage*) override;
|
||||||
|
|
||||||
|
|||||||
@@ -107,6 +107,8 @@ const int64_t &Stream::duration() const
|
|||||||
void Stream::set_duration(const int64_t &duration)
|
void Stream::set_duration(const int64_t &duration)
|
||||||
{
|
{
|
||||||
duration_ = duration;
|
duration_ = duration;
|
||||||
|
|
||||||
|
emit ParametersChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Stream::enabled() const
|
bool Stream::enabled() const
|
||||||
|
|||||||
@@ -115,6 +115,8 @@ protected:
|
|||||||
signals:
|
signals:
|
||||||
void IndexChanged();
|
void IndexChanged();
|
||||||
|
|
||||||
|
void ParametersChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Footage* footage_;
|
Footage* footage_;
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,8 @@
|
|||||||
const int64_t VideoStream::kEndTimestamp = AV_NOPTS_VALUE;
|
const int64_t VideoStream::kEndTimestamp = AV_NOPTS_VALUE;
|
||||||
|
|
||||||
VideoStream::VideoStream() :
|
VideoStream::VideoStream() :
|
||||||
start_time_(0)
|
start_time_(0),
|
||||||
|
is_image_sequence_(false)
|
||||||
{
|
{
|
||||||
set_type(kVideo);
|
set_type(kVideo);
|
||||||
}
|
}
|
||||||
@@ -57,6 +58,17 @@ const int64_t &VideoStream::start_time() const
|
|||||||
void VideoStream::set_start_time(const int64_t &start_time)
|
void VideoStream::set_start_time(const int64_t &start_time)
|
||||||
{
|
{
|
||||||
start_time_ = 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)
|
int64_t VideoStream::get_closest_timestamp_in_frame_index(const rational &time)
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
class VideoStream : public ImageStream
|
class VideoStream : public ImageStream
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
VideoStream();
|
VideoStream();
|
||||||
|
|
||||||
@@ -43,6 +44,9 @@ public:
|
|||||||
const int64_t& start_time() const;
|
const int64_t& start_time() const;
|
||||||
void set_start_time(const int64_t& start_time);
|
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(const rational& time);
|
||||||
int64_t get_closest_timestamp_in_frame_index(int64_t timestamp);
|
int64_t get_closest_timestamp_in_frame_index(int64_t timestamp);
|
||||||
void clear_frame_index();
|
void clear_frame_index();
|
||||||
@@ -62,6 +66,8 @@ private:
|
|||||||
|
|
||||||
QMutex index_access_lock_;
|
QMutex index_access_lock_;
|
||||||
|
|
||||||
|
bool is_image_sequence_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using VideoStreamPtr = std::shared_ptr<VideoStream>;
|
using VideoStreamPtr = std::shared_ptr<VideoStream>;
|
||||||
|
|||||||
@@ -179,6 +179,8 @@ void VideoRenderWorker::HashNodeRecursively(QCryptographicHash *hash, const Node
|
|||||||
if (stream->type() == Stream::kVideo) {
|
if (stream->type() == Stream::kVideo) {
|
||||||
hash->addData(QStringLiteral("%1/%2").arg(QString::number(input_time.numerator()),
|
hash->addData(QStringLiteral("%1/%2").arg(QString::number(input_time.numerator()),
|
||||||
QString::number(input_time.denominator())).toUtf8());
|
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);
|
/*Decoder::RetrieveState state = decoder->GetRetrieveState(input_time);
|
||||||
|
|
||||||
if (state == Decoder::kReady) {
|
if (state == Decoder::kReady) {
|
||||||
|
|||||||
Reference in New Issue
Block a user