use frame rate and timebase less interchangeably
This commit is contained in:
@@ -219,7 +219,7 @@ void FFmpegEncoder::WriteAudio(AudioParams pcm_info, QIODevice* file)
|
||||
// If not, use another frame size
|
||||
if (params().video_enabled()) {
|
||||
// If we're encoding video, use enough samples to cover roughly one frame of video
|
||||
maximum_frame_samples = params().audio_params().time_to_samples(params().video_params().time_base());
|
||||
maximum_frame_samples = params().audio_params().time_to_samples(params().video_params().frame_rate_as_time_base());
|
||||
} else {
|
||||
// If no video, just use an arbitrary number
|
||||
maximum_frame_samples = 256;
|
||||
@@ -484,7 +484,7 @@ bool FFmpegEncoder::InitializeStream(AVMediaType type, AVStream** stream_ptr, AV
|
||||
codec_ctx->width = params().video_params().width();
|
||||
codec_ctx->height = params().video_params().height();
|
||||
codec_ctx->sample_aspect_ratio = params().video_params().pixel_aspect_ratio().toAVRational();
|
||||
codec_ctx->time_base = params().video_params().time_base().toAVRational();
|
||||
codec_ctx->time_base = params().video_params().frame_rate_as_time_base().toAVRational();
|
||||
codec_ctx->pix_fmt = av_get_pix_fmt(params().video_pix_fmt().toUtf8());
|
||||
|
||||
if (params().video_params().interlacing() != VideoParams::kInterlaceNone) {
|
||||
|
||||
@@ -281,11 +281,19 @@ int64_t Timecode::time_to_timestamp(const double &time, const rational &timebase
|
||||
|
||||
int64_t Timecode::rescale_timestamp(const int64_t &ts, const rational &source, const rational &dest)
|
||||
{
|
||||
if (source == dest) {
|
||||
return ts;
|
||||
}
|
||||
|
||||
return qRound64(static_cast<double>(ts) * source.toDouble() / dest.toDouble());
|
||||
}
|
||||
|
||||
int64_t Timecode::rescale_timestamp_ceil(const int64_t &ts, const rational &source, const rational &dest)
|
||||
{
|
||||
if (source == dest) {
|
||||
return ts;
|
||||
}
|
||||
|
||||
return qCeil(static_cast<double>(ts) * source.toDouble() / dest.toDouble());
|
||||
}
|
||||
|
||||
|
||||
@@ -195,7 +195,7 @@ ExportDialog::ExportDialog(ViewerOutput *viewer_node, QWidget *parent) :
|
||||
video_tab_->width_slider()->SetDefaultValue(vp.width());
|
||||
video_tab_->height_slider()->SetValue(vp.height());
|
||||
video_tab_->height_slider()->SetDefaultValue(vp.height());
|
||||
video_tab_->frame_rate_combobox()->SetFrameRate(vp.time_base().flipped());
|
||||
video_tab_->frame_rate_combobox()->SetFrameRate(vp.frame_rate());
|
||||
video_tab_->pixel_aspect_combobox()->SetPixelAspectRatio(vp.pixel_aspect_ratio());
|
||||
video_tab_->pixel_format_field()->SetPixelFormat(static_cast<VideoParams::Format>(Config::Current()["OnlinePixelFormat"].toInt()));
|
||||
video_tab_->interlaced_combobox()->SetInterlaceMode(vp.interlacing());
|
||||
|
||||
@@ -92,30 +92,13 @@ QString ViewerOutput::Description() const
|
||||
|
||||
QString ViewerOutput::duration() const
|
||||
{
|
||||
/*rational timeline_length = GetLength();
|
||||
|
||||
rational timebase = GetVideoParams().time_base();
|
||||
|
||||
int64_t timestamp = Timecode::time_to_timestamp(timeline_length, timebase);
|
||||
|
||||
return Timecode::timestamp_to_timecode(timestamp, timebase, Core::instance()->GetTimecodeDisplay());*/
|
||||
// Try video first
|
||||
VideoParams video = GetFirstEnabledVideoStream();
|
||||
|
||||
if (video.is_valid() && video.video_type() != VideoParams::kVideoTypeStill) {
|
||||
int64_t duration = video.duration();
|
||||
rational frame_rate_timebase = video.frame_rate_as_time_base();
|
||||
|
||||
rational frame_rate_timebase = video.frame_rate().flipped();
|
||||
if (frame_rate_timebase.isNull()) {
|
||||
frame_rate_timebase = video.time_base();
|
||||
}
|
||||
|
||||
if (video.time_base() != frame_rate_timebase) {
|
||||
// Convert from timebase to frame rate
|
||||
duration = Timecode::rescale_timestamp_ceil(duration, video.time_base(), frame_rate_timebase);
|
||||
}
|
||||
|
||||
return Timecode::timestamp_to_timecode(duration,
|
||||
return Timecode::timestamp_to_timecode(Timecode::rescale_timestamp_ceil(video.duration(), video.time_base(), frame_rate_timebase),
|
||||
frame_rate_timebase,
|
||||
Core::instance()->GetTimecodeDisplay());
|
||||
}
|
||||
@@ -147,13 +130,7 @@ QString ViewerOutput::rate() const
|
||||
VideoParams video_stream = GetFirstEnabledVideoStream();
|
||||
|
||||
if (video_stream.video_type() != VideoParams::kVideoTypeStill) {
|
||||
rational using_tb = video_stream.frame_rate();
|
||||
|
||||
if (using_tb.isNull()) {
|
||||
using_tb = video_stream.time_base().flipped();
|
||||
}
|
||||
|
||||
return tr("%1 FPS").arg(using_tb.toDouble());
|
||||
return tr("%1 FPS").arg(video_stream.frame_rate().toDouble());
|
||||
}
|
||||
} else if (HasEnabledAudioStreams()) {
|
||||
// No video streams, return audio
|
||||
@@ -414,7 +391,7 @@ void ViewerOutput::InputValueChangedEvent(const QString &input, int element)
|
||||
VideoParams new_video_params = GetVideoParams();
|
||||
|
||||
bool size_changed = cached_video_params_.width() != new_video_params.width() || cached_video_params_.height() != new_video_params.height();
|
||||
bool timebase_changed = cached_video_params_.time_base() != new_video_params.time_base();
|
||||
bool frame_rate_changed = cached_video_params_.frame_rate() != new_video_params.frame_rate();
|
||||
bool pixel_aspect_changed = cached_video_params_.pixel_aspect_ratio() != new_video_params.pixel_aspect_ratio();
|
||||
bool interlacing_changed = cached_video_params_.interlacing() != new_video_params.interlacing();
|
||||
|
||||
@@ -430,9 +407,9 @@ void ViewerOutput::InputValueChangedEvent(const QString &input, int element)
|
||||
emit InterlacingChanged(new_video_params.interlacing());
|
||||
}
|
||||
|
||||
if (timebase_changed) {
|
||||
video_frame_cache_.SetTimebase(new_video_params.time_base());
|
||||
emit TimebaseChanged(new_video_params.time_base());
|
||||
if (frame_rate_changed) {
|
||||
video_frame_cache_.SetTimebase(new_video_params.frame_rate_as_time_base());
|
||||
emit FrameRateChanged(new_video_params.frame_rate());
|
||||
}
|
||||
|
||||
emit VideoParamsChanged();
|
||||
@@ -479,7 +456,7 @@ void ViewerOutput::set_parameters_from_footage(const QVector<ViewerOutput *> foo
|
||||
// prioritize
|
||||
using_timebase = GetVideoParams().time_base();
|
||||
} else {
|
||||
using_timebase = s.frame_rate().flipped();
|
||||
using_timebase = s.frame_rate_as_time_base();
|
||||
found_video_params = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ public:
|
||||
static const uint64_t kVideoParamEditMask;
|
||||
|
||||
signals:
|
||||
void TimebaseChanged(const rational&);
|
||||
void FrameRateChanged(const rational&);
|
||||
|
||||
void LengthChanged(const rational& length);
|
||||
|
||||
|
||||
@@ -123,6 +123,39 @@ void Footage::InputValueChangedEvent(const QString &input, int element)
|
||||
AddStream(Track::kVideo, QVariant::fromValue(footage_info.GetVideoStreams().at(i)));
|
||||
}
|
||||
|
||||
if (!footage_info.GetVideoStreams().isEmpty()) {
|
||||
// FIXME: This will break on multiple video streams. Currently we don't have
|
||||
// infrastructure for different properties per element. We'll see if this becomes
|
||||
// a problem.
|
||||
VideoParams vp = footage_info.GetVideoStreams().first();
|
||||
|
||||
uint64_t video_param_mask = 0;
|
||||
|
||||
video_param_mask |= VideoParamEdit::kEnabled;
|
||||
video_param_mask |= VideoParamEdit::kColorspace;
|
||||
video_param_mask |= VideoParamEdit::kPixelAspect;
|
||||
video_param_mask |= VideoParamEdit::kInterlacing;
|
||||
video_param_mask |= VideoParamEdit::kFrameRateIsArbitrary;
|
||||
|
||||
if (vp.channel_count() == VideoParams::kRGBAChannelCount) {
|
||||
// Add premultiplied setting if this footage has an alpha channel
|
||||
video_param_mask |= VideoParamEdit::kPremultipliedAlpha;
|
||||
}
|
||||
|
||||
if (vp.video_type() == VideoParams::kVideoTypeVideo) {
|
||||
// This is video, ensure that the frame rate does not overwrite the timebase
|
||||
video_param_mask |= VideoParamEdit::kFrameRateIsNotTimebase;
|
||||
} else {
|
||||
// This is not a video, so it's either a still image or an image sequence
|
||||
video_param_mask |= VideoParamEdit::kIsImageSequence;
|
||||
video_param_mask |= VideoParamEdit::kStartTime;
|
||||
video_param_mask |= VideoParamEdit::kEndTime;
|
||||
video_param_mask |= VideoParamEdit::kFrameRate;
|
||||
}
|
||||
|
||||
SetInputProperty(kVideoParamsInput, QStringLiteral("mask"), QVariant::fromValue(video_param_mask));
|
||||
}
|
||||
|
||||
for (int i=0; i<footage_info.GetAudioStreams().size(); i++) {
|
||||
AddStream(Track::kAudio, QVariant::fromValue(footage_info.GetAudioStreams().at(i)));
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ public:
|
||||
format_(format)
|
||||
{
|
||||
set_default_footage_parameters();
|
||||
timebase_ = sample_rate_as_time_base();
|
||||
}
|
||||
|
||||
int sample_rate() const
|
||||
@@ -98,11 +99,7 @@ public:
|
||||
|
||||
rational time_base() const
|
||||
{
|
||||
if (timebase_.isNull()) {
|
||||
return rational(1, sample_rate());
|
||||
} else {
|
||||
return timebase_;
|
||||
}
|
||||
return timebase_;
|
||||
}
|
||||
|
||||
void set_time_base(const rational& timebase)
|
||||
@@ -110,6 +107,11 @@ public:
|
||||
timebase_ = timebase;
|
||||
}
|
||||
|
||||
rational sample_rate_as_time_base() const
|
||||
{
|
||||
return rational(1, sample_rate());
|
||||
}
|
||||
|
||||
Format format() const
|
||||
{
|
||||
return format_;
|
||||
|
||||
@@ -56,6 +56,7 @@ void FrameHashCache::SetHash(const rational &time, const QByteArray &hash, const
|
||||
if (job.range.Contains(time)
|
||||
&& job_time < job.job_time) {
|
||||
// Hash here has changed since this frame started rendering, discard it
|
||||
qDebug() << "Discarded hash because old";
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -71,6 +72,7 @@ void FrameHashCache::SetHash(const rational &time, const QByteArray &hash, const
|
||||
|
||||
void FrameHashCache::SetTimebase(const rational &tb)
|
||||
{
|
||||
qDebug() << "Hello timebase" << tb;
|
||||
timebase_ = tb;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ void RenderProcessor::Run()
|
||||
NodeOutput texture_output = viewer->GetConnectedTextureOutput();
|
||||
if (texture_output.IsValid()) {
|
||||
table = GenerateTable(texture_output.node(), texture_output.output(),
|
||||
TimeRange(time, time + video_params.time_base()));
|
||||
TimeRange(time, time + video_params.frame_rate_as_time_base()));
|
||||
}
|
||||
|
||||
TexturePtr texture = table.Get(NodeValue::kTexture).value<TexturePtr>();
|
||||
|
||||
@@ -112,7 +112,8 @@ VideoParams::VideoParams(int width, int height, const rational &time_base, Forma
|
||||
channel_count_(nb_channels),
|
||||
pixel_aspect_ratio_(pixel_aspect_ratio),
|
||||
interlacing_(interlacing),
|
||||
divider_(divider)
|
||||
divider_(divider),
|
||||
frame_rate_(time_base.flipped())
|
||||
{
|
||||
calculate_effective_size();
|
||||
validate_pixel_aspect_ratio();
|
||||
|
||||
@@ -122,6 +122,11 @@ public:
|
||||
time_base_ = r;
|
||||
}
|
||||
|
||||
rational frame_rate_as_time_base() const
|
||||
{
|
||||
return frame_rate_.flipped();
|
||||
}
|
||||
|
||||
int divider() const
|
||||
{
|
||||
return divider_;
|
||||
|
||||
@@ -163,7 +163,7 @@ void ExportTask::FrameDownloaded(FramePtr f, const QByteArray &hash, const QVect
|
||||
|
||||
forever {
|
||||
rational real_time = Timecode::timestamp_to_time(frame_time_,
|
||||
viewer()->GetVideoParams().time_base());
|
||||
viewer()->GetVideoParams().frame_rate_as_time_base());
|
||||
|
||||
if (!time_map_.contains(real_time)) {
|
||||
break;
|
||||
|
||||
@@ -51,7 +51,7 @@ bool RenderTask::Render(ColorManager* manager,
|
||||
|
||||
double progress_counter = 0;
|
||||
double total_length = 0;
|
||||
double video_frame_sz = video_params().time_base().toDouble();
|
||||
double video_frame_sz = video_params().frame_rate_as_time_base().toDouble();
|
||||
|
||||
// Store real time before any rendering takes place
|
||||
qint64 job_time = QDateTime::currentMSecsSinceEpoch();
|
||||
|
||||
@@ -74,46 +74,58 @@ ViewerOutput *TimeBasedWidget::GetConnectedNode() const
|
||||
|
||||
void TimeBasedWidget::ConnectViewerNode(ViewerOutput *node)
|
||||
{
|
||||
// Ignore no-op
|
||||
if (viewer_node_ == node) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (viewer_node_) {
|
||||
// Call potential derivative functions for disconnecting the viewer node
|
||||
DisconnectNodeInternal(viewer_node_);
|
||||
|
||||
// Disconnect length changed signal
|
||||
disconnect(viewer_node_, &ViewerOutput::LengthChanged, this, &TimeBasedWidget::UpdateMaximumScroll);
|
||||
disconnect(viewer_node_, &ViewerOutput::TimebaseChanged, this, &TimeBasedWidget::SetTimebase);
|
||||
|
||||
if (auto_set_timebase_) {
|
||||
SetTimebase(rational());
|
||||
}
|
||||
// Reset timebase to null
|
||||
SetTimebase(rational());
|
||||
|
||||
// Disconnect ruler and scrollbar from timeline points
|
||||
ruler()->ConnectTimelinePoints(nullptr);
|
||||
scrollbar_->ConnectTimelinePoints(nullptr);
|
||||
}
|
||||
|
||||
// Set viewer node
|
||||
viewer_node_ = node;
|
||||
|
||||
// Call derivatives
|
||||
ConnectedNodeChanged(viewer_node_);
|
||||
|
||||
if (viewer_node_) {
|
||||
// Connect length changed signal
|
||||
connect(viewer_node_, &ViewerOutput::LengthChanged, this, &TimeBasedWidget::UpdateMaximumScroll);
|
||||
|
||||
// Connect ruler and scrollbar to timeline points
|
||||
ruler()->ConnectTimelinePoints(viewer_node_->GetTimelinePoints());
|
||||
scrollbar_->ConnectTimelinePoints(viewer_node_->GetTimelinePoints());
|
||||
|
||||
// If we're setting the timebase, set it automatically based on the video and audio parameters
|
||||
if (auto_set_timebase_) {
|
||||
if (!viewer_node_->GetVideoParams().time_base().isNull()) {
|
||||
SetTimebase(viewer_node_->GetVideoParams().time_base());
|
||||
} else if (viewer_node_->GetAudioParams().sample_rate() > 0) {
|
||||
SetTimebase(viewer_node_->GetAudioParams().time_base());
|
||||
} else {
|
||||
SetTimebase(rational());
|
||||
}
|
||||
rational video_tb = viewer_node_->GetVideoParams().frame_rate_as_time_base();
|
||||
|
||||
connect(viewer_node_, &ViewerOutput::TimebaseChanged, this, &TimeBasedWidget::SetTimebase);
|
||||
if (!video_tb.isNull()) {
|
||||
SetTimebase(video_tb);
|
||||
} else {
|
||||
rational audio_tb = viewer_node_->GetAudioParams().sample_rate_as_time_base();
|
||||
|
||||
if (!audio_tb.isNull()) {
|
||||
SetTimebase(audio_tb);
|
||||
} else {
|
||||
SetTimebase(rational());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call derivatives
|
||||
ConnectNodeInternal(viewer_node_);
|
||||
}
|
||||
|
||||
|
||||
@@ -224,11 +224,10 @@ void TimelineWidget::ConnectNodeInternal(ViewerOutput *n)
|
||||
|
||||
connect(s, &Sequence::TrackAdded, this, &TimelineWidget::AddTrack);
|
||||
connect(s, &Sequence::TrackRemoved, this, &TimelineWidget::RemoveTrack);
|
||||
connect(n, &ViewerOutput::TimebaseChanged, this, &TimelineWidget::SetTimebase);
|
||||
|
||||
ruler()->SetPlaybackCache(n->video_frame_cache());
|
||||
|
||||
SetTimebase(n->GetVideoParams().time_base());
|
||||
SetTimebase(n->GetVideoParams().frame_rate_as_time_base());
|
||||
|
||||
for (int i=0;i<views_.size();i++) {
|
||||
Track::Type track_type = static_cast<Track::Type>(i);
|
||||
@@ -253,7 +252,6 @@ void TimelineWidget::DisconnectNodeInternal(ViewerOutput *n)
|
||||
|
||||
disconnect(s, &Sequence::TrackAdded, this, &TimelineWidget::AddTrack);
|
||||
disconnect(s, &Sequence::TrackRemoved, this, &TimelineWidget::RemoveTrack);
|
||||
disconnect(n, &ViewerOutput::TimebaseChanged, this, &TimelineWidget::SetTimebase);
|
||||
|
||||
DeselectAll();
|
||||
|
||||
|
||||
@@ -281,7 +281,7 @@ void ImportTool::PrepGhosts(const rational& frame, const int& track_index)
|
||||
if (parent()->GetConnectedNode()) {
|
||||
FootageToGhosts(frame,
|
||||
dragged_footage_,
|
||||
parent()->timebase(),
|
||||
parent()->GetConnectedNode()->GetVideoParams().time_base(),
|
||||
track_index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +97,10 @@ VideoParamEdit::VideoParamEdit(QWidget* parent) :
|
||||
connect(frame_rate_combobox_, static_cast<void (FrameRateComboBox::*)(int)>(&FrameRateComboBox::currentIndexChanged), this, &VideoParamEdit::Changed);
|
||||
layout->addWidget(frame_rate_combobox_, row, 1);
|
||||
|
||||
frame_rate_slider_ = new FloatSlider();
|
||||
connect(frame_rate_slider_, &FloatSlider::ValueChanged, this, &VideoParamEdit::Changed);
|
||||
layout->addWidget(frame_rate_slider_, row, 1);
|
||||
|
||||
row++;
|
||||
|
||||
// Pixel Aspect Ratio
|
||||
@@ -215,7 +219,8 @@ void VideoParamEdit::SetParameterMask(uint64_t mask)
|
||||
depth_slider_->setVisible(mask & kDepth);
|
||||
|
||||
frame_rate_lbl_->setVisible(mask & kFrameRate);
|
||||
frame_rate_combobox_->setVisible(mask & kFrameRate);
|
||||
frame_rate_combobox_->setVisible((mask & kFrameRate) && (mask & ~kFrameRateIsArbitrary));
|
||||
frame_rate_slider_->setVisible((mask & kFrameRate) && (mask & kFrameRateIsArbitrary));
|
||||
|
||||
pixel_aspect_lbl_->setVisible(mask & kPixelAspect);
|
||||
pixel_aspect_combobox_->setVisible(mask & kPixelAspect);
|
||||
@@ -263,12 +268,22 @@ VideoParams VideoParamEdit::GetVideoParams() const
|
||||
p.set_height(height_slider_->GetValue());
|
||||
p.set_depth(depth_slider_->GetValue());
|
||||
|
||||
p.set_frame_rate(frame_rate_combobox_->GetFrameRate());
|
||||
if (mask_ & kFrameRateIsNotTimebase) {
|
||||
// Frame rate editor will only edit the frame rate
|
||||
p.set_time_base(timebase_temp_);
|
||||
} else {
|
||||
p.set_time_base(frame_rate_combobox_->GetFrameRate().flipped());
|
||||
{
|
||||
rational using_frame_rate;
|
||||
|
||||
if (mask_ & kFrameRateIsArbitrary) {
|
||||
using_frame_rate = rational::fromDouble(frame_rate_slider_->GetValue());
|
||||
} else {
|
||||
using_frame_rate = frame_rate_combobox_->GetFrameRate();
|
||||
}
|
||||
|
||||
p.set_frame_rate(using_frame_rate);
|
||||
if (mask_ & kFrameRateIsNotTimebase) {
|
||||
// Frame rate editor will only edit the frame rate
|
||||
p.set_time_base(timebase_temp_);
|
||||
} else {
|
||||
p.set_time_base(using_frame_rate.flipped());
|
||||
}
|
||||
}
|
||||
|
||||
p.set_pixel_aspect_ratio(pixel_aspect_combobox_->GetPixelAspectRatio());
|
||||
@@ -295,14 +310,9 @@ void VideoParamEdit::SetVideoParams(const VideoParams &p)
|
||||
height_slider_->SetValue(p.height());
|
||||
depth_slider_->SetValue(p.depth());
|
||||
|
||||
if (mask_ & kFrameRateIsNotTimebase) {
|
||||
// Frame rate editor will only edit the frame rate
|
||||
frame_rate_combobox_->SetFrameRate(p.frame_rate());
|
||||
timebase_temp_ = p.time_base();
|
||||
} else {
|
||||
// Frame rate editor will edit both frame rate and time base
|
||||
frame_rate_combobox_->SetFrameRate(p.time_base().flipped());
|
||||
}
|
||||
frame_rate_combobox_->SetFrameRate(p.frame_rate());
|
||||
frame_rate_slider_->SetValue(p.frame_rate().toDouble());
|
||||
timebase_temp_ = p.time_base();
|
||||
|
||||
pixel_aspect_combobox_->SetPixelAspectRatio(p.pixel_aspect_ratio());
|
||||
interlaced_combobox_->SetInterlaceMode(p.interlacing());
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "render/colormanager.h"
|
||||
#include "render/videoparams.h"
|
||||
#include "widget/slider/floatslider.h"
|
||||
#include "widget/slider/integerslider.h"
|
||||
#include "widget/standardcombos/frameratecombobox.h"
|
||||
#include "widget/standardcombos/interlacedcombobox.h"
|
||||
@@ -60,6 +61,7 @@ public:
|
||||
kPremultipliedAlpha = 0x2000,
|
||||
kColorspace = 0x4000,
|
||||
kFrameRateIsNotTimebase = 0x8000,
|
||||
kFrameRateIsArbitrary = 0x10000
|
||||
};
|
||||
|
||||
void SetParameterMask(uint64_t mask);
|
||||
@@ -143,6 +145,7 @@ private:
|
||||
IntegerSlider* depth_slider_;
|
||||
QLabel* frame_rate_lbl_;
|
||||
FrameRateComboBox* frame_rate_combobox_;
|
||||
FloatSlider* frame_rate_slider_;
|
||||
QLabel* pixel_aspect_lbl_;
|
||||
PixelAspectRatioComboBox* pixel_aspect_combobox_;
|
||||
QLabel* interlaced_lbl_;
|
||||
|
||||
@@ -71,10 +71,13 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
|
||||
stack_->addWidget(sizer_);
|
||||
|
||||
display_widget_ = new ViewerDisplayWidget();
|
||||
display_widget_->setAcceptDrops(true);
|
||||
connect(display_widget_, &ViewerDisplayWidget::customContextMenuRequested, this, &ViewerWidget::ShowContextMenu);
|
||||
connect(display_widget_, &ViewerDisplayWidget::CursorColor, this, &ViewerWidget::CursorColor);
|
||||
connect(display_widget_, &ViewerDisplayWidget::ColorProcessorChanged, this, &ViewerWidget::ColorProcessorChanged);
|
||||
connect(display_widget_, &ViewerDisplayWidget::ColorManagerChanged, this, &ViewerWidget::ColorManagerChanged);
|
||||
connect(display_widget_, &ViewerDisplayWidget::DragEntered, this, &ViewerWidget::DragEntered);
|
||||
connect(display_widget_, &ViewerDisplayWidget::Dropped, this, &ViewerWidget::Dropped);
|
||||
connect(sizer_, &ViewerSizer::RequestScale, display_widget_, &ViewerDisplayWidget::SetMatrixZoom);
|
||||
connect(sizer_, &ViewerSizer::RequestTranslate, display_widget_, &ViewerDisplayWidget::SetMatrixTranslate);
|
||||
connect(display_widget_, &ViewerDisplayWidget::HandDragMoved, sizer_, &ViewerSizer::HandDragMove);
|
||||
@@ -118,6 +121,8 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
|
||||
SetAutoMaxScrollBar(true);
|
||||
|
||||
instances_.append(this);
|
||||
|
||||
setAcceptDrops(true);
|
||||
}
|
||||
|
||||
ViewerWidget::~ViewerWidget()
|
||||
@@ -1214,4 +1219,37 @@ void ViewerWidget::ViewerShiftedRange(const rational &from, const rational &to)
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerWidget::DragEntered(QDragEnterEvent* event)
|
||||
{
|
||||
if (event->mimeData()->formats().contains(QStringLiteral("application/x-oliveprojectitemdata"))) {
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerWidget::Dropped(QDropEvent *event)
|
||||
{
|
||||
QByteArray mimedata = event->mimeData()->data(QStringLiteral("application/x-oliveprojectitemdata"));
|
||||
QDataStream stream(&mimedata, QIODevice::ReadOnly);
|
||||
|
||||
// Variables to deserialize into
|
||||
quintptr item_ptr = 0;
|
||||
QVector<Track::Reference> enabled_streams;
|
||||
|
||||
while (!stream.atEnd()) {
|
||||
stream >> enabled_streams >> item_ptr;
|
||||
|
||||
// We only need the one item
|
||||
break;
|
||||
}
|
||||
|
||||
if (item_ptr) {
|
||||
Node* item = reinterpret_cast<Node*>(item_ptr);
|
||||
ViewerOutput* viewer = dynamic_cast<ViewerOutput*>(item);
|
||||
|
||||
if (viewer) {
|
||||
ConnectViewerNode(viewer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -288,6 +288,10 @@ private slots:
|
||||
|
||||
void TimeChangedFromWaveform(qint64 t);
|
||||
|
||||
void DragEntered(QDragEnterEvent* event);
|
||||
|
||||
void Dropped(QDropEvent* event);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -278,20 +278,29 @@ void ViewerDisplayWidget::mouseReleaseEvent(QMouseEvent *event)
|
||||
|
||||
void ViewerDisplayWidget::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
emit DragEntered();
|
||||
super::dragEnterEvent(event);
|
||||
emit DragEntered(event);
|
||||
|
||||
if (!event->isAccepted()) {
|
||||
super::dragEnterEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerDisplayWidget::dragLeaveEvent(QDragLeaveEvent *event)
|
||||
{
|
||||
emit DragLeft();
|
||||
super::dragLeaveEvent(event);
|
||||
emit DragLeft(event);
|
||||
|
||||
if (!event->isAccepted()) {
|
||||
super::dragLeaveEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerDisplayWidget::dropEvent(QDropEvent *event)
|
||||
{
|
||||
emit Dropped();
|
||||
super::dropEvent(event);
|
||||
emit Dropped(event);
|
||||
|
||||
if (!event->isAccepted()) {
|
||||
super::dropEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerDisplayWidget::OnPaint()
|
||||
@@ -345,7 +354,7 @@ void ViewerDisplayWidget::OnPaint()
|
||||
rational node_time = GetGizmoTime();
|
||||
|
||||
gizmo_db_ = gt.GenerateDatabase(gizmos_, TimeRange(node_time,
|
||||
node_time + gizmo_params_.time_base()));
|
||||
node_time + gizmo_params_.frame_rate_as_time_base()));
|
||||
|
||||
QPainter p(inner_widget());
|
||||
p.setWorldTransform(GenerateGizmoTransform());
|
||||
|
||||
@@ -170,11 +170,11 @@ signals:
|
||||
*/
|
||||
void CursorColor(const Color& reference, const Color& display);
|
||||
|
||||
void DragEntered();
|
||||
void DragEntered(QDragEnterEvent* event);
|
||||
|
||||
void DragLeft();
|
||||
void DragLeft(QDragLeaveEvent* event);
|
||||
|
||||
void Dropped();
|
||||
void Dropped(QDropEvent* event);
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user