various: implement sequence pixel aspect ratios and interlacing settings

Implements the following:
- Sequences have pixel aspect ratios that work in tandem with footage PARs
  to render footage correctly. Viewer and export also acknowledge PARs
- Sequences can have interlacing settings. This doesn't do anything yet,
  eventually the renderer will need to interlace/deinterlace/reinterlace
  appropriately in order to conform all the footage to the sequence. Export
  acknowledges interlacing, but this only affects metadata, not the image.
This commit is contained in:
itsmattkc
2020-08-10 01:47:26 +10:00
parent 901f1001af
commit 28dcff10c0
51 changed files with 1201 additions and 605 deletions
@@ -35,8 +35,16 @@ SequenceDialogParameterTab::SequenceDialogParameterTab(Sequence* sequence, QWidg
video_layout->addWidget(video_height_field_, row, 1);
row++;
video_layout->addWidget(new QLabel(tr("Frame Rate:")), row, 0);
video_frame_rate_field_ = new QComboBox();
video_frame_rate_field_ = new FrameRateComboBox();
video_layout->addWidget(video_frame_rate_field_, row, 1);
row++;
video_layout->addWidget(new QLabel(tr("Pixel Aspect Ratio:")), row, 0);
video_pixel_aspect_field_ = new PixelAspectRatioComboBox();
video_layout->addWidget(video_pixel_aspect_field_, row, 1);
row++;
video_layout->addWidget(new QLabel(tr("Interlacing:")));
video_interlaced_field_ = new InterlacedComboBox();
video_layout->addWidget(video_interlaced_field_, row, 1);
layout->addWidget(video_group);
row = 0;
@@ -46,11 +54,11 @@ SequenceDialogParameterTab::SequenceDialogParameterTab(Sequence* sequence, QWidg
audio_group->setTitle(tr("Audio"));
QGridLayout* audio_layout = new QGridLayout(audio_group);
audio_layout->addWidget(new QLabel(tr("Sample Rate:")), row, 0);
audio_sample_rate_field_ = new QComboBox();
audio_sample_rate_field_ = new SampleRateComboBox();
audio_layout->addWidget(audio_sample_rate_field_, row, 1);
row++;
audio_layout->addWidget(new QLabel(tr("Channels:")), row, 0);
audio_channels_field_ = new QComboBox();
audio_channels_field_ = new ChannelLayoutComboBox();
audio_layout->addWidget(audio_channels_field_, row, 1);
layout->addWidget(audio_group);
@@ -61,83 +69,29 @@ SequenceDialogParameterTab::SequenceDialogParameterTab(Sequence* sequence, QWidg
preview_group->setTitle(tr("Preview"));
QGridLayout* preview_layout = new QGridLayout(preview_group);
preview_layout->addWidget(new QLabel(tr("Resolution:")), row, 0);
preview_resolution_field_ = new QComboBox();
preview_resolution_field_ = new VideoDividerComboBox();
preview_layout->addWidget(preview_resolution_field_, row, 1);
preview_resolution_label_ = new QLabel();
preview_layout->addWidget(preview_resolution_label_, row, 2);
row++;
preview_layout->addWidget(new QLabel(tr("Format:")), row, 0);
preview_format_field_ = new QComboBox();
preview_format_field_ = new PixelFormatComboBox(true, true);
preview_layout->addWidget(preview_format_field_, row, 1, 1, 2);
layout->addWidget(preview_group);
// Set up available frame rates
frame_rate_list_ = Core::SupportedFrameRates();
foreach (const rational& fr, frame_rate_list_) {
video_frame_rate_field_->addItem(Core::FrameRateToString(fr));
}
// Set up available sample rates
sample_rate_list_ = Core::SupportedSampleRates();
foreach (const int& sr, sample_rate_list_) {
audio_sample_rate_field_->addItem(Core::SampleRateToString(sr));
}
// Set up available channel layouts
channel_layout_list_ = Core::SupportedChannelLayouts();
foreach (const uint64_t& ch_layout, channel_layout_list_) {
audio_channels_field_->addItem(Core::ChannelLayoutToString(ch_layout), QVariant::fromValue(ch_layout));
}
// Set up preview dividers
divider_list_ = Core::SupportedDividers();
foreach (int d, divider_list_) {
QString name;
if (d == 1) {
name = tr("Full");
} else {
name = tr("1/%1").arg(d);
}
preview_resolution_field_->addItem(name);
}
connect(preview_resolution_field_, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, &SequenceDialogParameterTab::UpdatePreviewResolutionLabel);
// Set up preview formats
for (int i=0;i<PixelFormat::PIX_FMT_COUNT;i++) {
PixelFormat::Format pix_fmt = static_cast<PixelFormat::Format>(i);
// We always render with an alpha channel internally
if (PixelFormat::FormatHasAlphaChannel(pix_fmt)
&& PixelFormat::FormatIsFloat(pix_fmt)) {
preview_format_field_->addItem(PixelFormat::GetName(pix_fmt));
preview_format_list_.append(pix_fmt);
}
}
// Set values based on input sequence
video_width_field_->SetValue(sequence->video_params().width());
video_height_field_->SetValue(sequence->video_params().height());
video_frame_rate_field_->SetFrameRate(sequence->video_params().time_base().flipped());
video_pixel_aspect_field_->SetPixelAspectRatio(sequence->video_params().pixel_aspect_ratio());
video_interlaced_field_->SetInterlaceMode(sequence->video_params().interlacing());
preview_resolution_field_->SetDivider(sequence->video_params().divider());
preview_format_field_->SetPixelFormat(sequence->video_params().format());
audio_sample_rate_field_->SetSampleRate(sequence->audio_params().sample_rate());
audio_channels_field_->SetChannelLayout(sequence->audio_params().channel_layout());
int frame_rate_index = frame_rate_list_.indexOf(sequence->video_params().time_base().flipped());
video_frame_rate_field_->setCurrentIndex(frame_rate_index);
int sample_rate_index = sample_rate_list_.indexOf(sequence->audio_params().sample_rate());
audio_sample_rate_field_->setCurrentIndex(sample_rate_index);
for (int i=0;i<audio_channels_field_->count();i++) {
if (audio_channels_field_->itemData(i).toULongLong() == sequence->audio_params().channel_layout()) {
audio_channels_field_->setCurrentIndex(i);
break;
}
}
preview_resolution_field_->setCurrentIndex(divider_list_.indexOf(sequence->video_params().divider()));
preview_format_field_->setCurrentIndex(preview_format_list_.indexOf(sequence->video_params().format()));
connect(preview_resolution_field_, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, &SequenceDialogParameterTab::UpdatePreviewResolutionLabel);
layout->addStretch();
@@ -148,62 +102,31 @@ SequenceDialogParameterTab::SequenceDialogParameterTab(Sequence* sequence, QWidg
UpdatePreviewResolutionLabel();
}
int SequenceDialogParameterTab::GetSelectedVideoWidth() const
{
return video_width_field_->GetValue();
}
int SequenceDialogParameterTab::GetSelectedVideoHeight() const
{
return video_height_field_->GetValue();
}
const rational &SequenceDialogParameterTab::GetSelectedVideoFrameRate() const
{
return frame_rate_list_.at(video_frame_rate_field_->currentIndex());
}
int SequenceDialogParameterTab::GetSelectedAudioSampleRate() const
{
return sample_rate_list_.at(audio_sample_rate_field_->currentIndex());
}
uint64_t SequenceDialogParameterTab::GetSelectedAudioChannelLayout() const
{
return audio_channels_field_->currentData().toULongLong();
}
int SequenceDialogParameterTab::GetSelectedPreviewResolution() const
{
return divider_list_.at(preview_resolution_field_->currentIndex());
}
PixelFormat::Format SequenceDialogParameterTab::GetSelectedPreviewFormat() const
{
return preview_format_list_.at(preview_format_field_->currentIndex());
}
void SequenceDialogParameterTab::PresetChanged(const SequencePreset &preset)
{
video_width_field_->SetValue(preset.width());
video_height_field_->SetValue(preset.height());
video_frame_rate_field_->setCurrentIndex(frame_rate_list_.indexOf(preset.frame_rate()));
audio_sample_rate_field_->setCurrentIndex(sample_rate_list_.indexOf(preset.sample_rate()));
audio_channels_field_->setCurrentIndex(channel_layout_list_.indexOf(preset.channel_layout()));
preview_resolution_field_->setCurrentIndex(divider_list_.indexOf(preset.preview_divider()));
preview_format_field_->setCurrentIndex(preview_format_list_.indexOf(preset.preview_format()));
video_frame_rate_field_->SetFrameRate(preset.frame_rate());
video_pixel_aspect_field_->SetPixelAspectRatio(preset.pixel_aspect());
video_interlaced_field_->SetInterlaceMode(preset.interlacing());
audio_sample_rate_field_->SetSampleRate(preset.sample_rate());
audio_channels_field_->SetChannelLayout(preset.channel_layout());
preview_resolution_field_->SetDivider(preset.preview_divider());
preview_format_field_->SetPixelFormat(preset.preview_format());
}
void SequenceDialogParameterTab::SavePresetClicked()
{
emit SaveParametersAsPreset({QString(),
static_cast<int>(video_width_field_->GetValue()),
static_cast<int>(video_height_field_->GetValue()),
frame_rate_list_.at(video_frame_rate_field_->currentIndex()),
sample_rate_list_.at(audio_sample_rate_field_->currentIndex()),
channel_layout_list_.at(audio_channels_field_->currentIndex()),
divider_list_.at(preview_resolution_field_->currentIndex()),
preview_format_list_.at(preview_format_field_->currentIndex())});
GetSelectedVideoWidth(),
GetSelectedVideoHeight(),
GetSelectedVideoFrameRate(),
GetSelectedVideoPixelAspect(),
GetSelectedVideoInterlacingMode(),
GetSelectedAudioSampleRate(),
GetSelectedAudioChannelLayout(),
GetSelectedPreviewResolution(),
GetSelectedPreviewFormat()});
}
void SequenceDialogParameterTab::UpdatePreviewResolutionLabel()
@@ -211,7 +134,9 @@ void SequenceDialogParameterTab::UpdatePreviewResolutionLabel()
VideoParams test_param(video_width_field_->GetValue(),
video_height_field_->GetValue(),
PixelFormat::PIX_FMT_INVALID,
divider_list_.at(preview_resolution_field_->currentIndex()));
rational(1),
VideoParams::kInterlaceNone,
preview_resolution_field_->currentData().toInt());
preview_resolution_label_->setText(tr("(%1x%2)").arg(QString::number(test_param.effective_width()),
QString::number(test_param.effective_height())));