diff --git a/src/dispatch.cpp b/src/dispatch.cpp index 31edc07..85eb4e0 100644 --- a/src/dispatch.cpp +++ b/src/dispatch.cpp @@ -491,6 +491,9 @@ void dispatch::receive_cmd(const command& cmd) if (_input_data.params.crop_aspect_ratio_is_set()) _parameters.set_crop_aspect_ratio(_input_data.params.crop_aspect_ratio()); notify_all(notification::crop_aspect_ratio); + if (_input_data.params.source_aspect_ratio_is_set()) + _parameters.set_source_aspect_ratio(_input_data.params.source_aspect_ratio()); + notify_all(notification::source_aspect_ratio); if (_input_data.params.parallax_is_set()) _parameters.set_parallax(_input_data.params.parallax()); notify_all(notification::parallax); @@ -798,6 +801,13 @@ void dispatch::receive_cmd(const command& cmd) } notify_all(notification::crop_aspect_ratio); break; + case command::set_source_aspect_ratio: + { + float x = s11n::load(p); + _parameters.set_source_aspect_ratio((x <= 0.0f ? 0.0f : clamp(x, 1.0f, 2.39f))); + } + notify_all(notification::source_aspect_ratio); + break; case command::adjust_parallax: _parameters.set_parallax(clamp(_parameters.parallax() + s11n::load(p), -1.0f, +1.0f)); notify_all(notification::parallax); @@ -1185,6 +1195,9 @@ bool dispatch::parse_command(const std::string& s, command* c) } else if (tokens.size() == 2 && tokens[0] == "set-crop-aspect-ratio" && parse_aspect_ratio(tokens[1], &p.f)) { *c = command(command::set_crop_aspect_ratio, p.f); + } else if (tokens.size() == 2 && tokens[0] == "set-source-aspect-ratio" + && parse_aspect_ratio(tokens[1], &p.f)) { + *c = command(command::set_source_aspect_ratio, p.f); } else if (tokens.size() == 2 && tokens[0] == "set-parallax" && str::to(tokens[1], &p.f)) { *c = command(command::set_parallax, p.f); diff --git a/src/dispatch.h b/src/dispatch.h index 8aa73be..b5f7fca 100644 --- a/src/dispatch.h +++ b/src/dispatch.h @@ -135,6 +135,7 @@ public: set_stereo_layout, // video_frame::stereo_layout set_stereo_layout_swap, // bool set_crop_aspect_ratio, // float + set_source_aspect_ratio, // float set_parallax, // float (absolute value) adjust_parallax, // float (relative adjustment) set_ghostbust, // float (absolute value) @@ -254,6 +255,7 @@ public: stereo_layout, stereo_layout_swap, crop_aspect_ratio, + source_aspect_ratio, parallax, ghostbust, subtitle_parallax, diff --git a/src/gui.cpp b/src/gui.cpp index fd8d3ff..eb63467 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -1960,6 +1960,23 @@ video_dialog::video_dialog(QWidget *parent) : QDialog(parent), _lock(false) _crop_ar_combobox->addItem("1:1"); connect(_crop_ar_combobox, SIGNAL(currentIndexChanged(int)), this, SLOT(crop_ar_changed())); + QLabel *source_ar_label = new QLabel(_("Force source aspect ratio:")); + source_ar_label->setToolTip(_("

Force the aspect ratio of video source.

")); + _source_ar_combobox = new QComboBox(); + _source_ar_combobox->setToolTip(source_ar_label->toolTip()); + _source_ar_combobox->addItem(_("Do not force")); + _source_ar_combobox->addItem("16:10"); + _source_ar_combobox->addItem("16:9"); + _source_ar_combobox->addItem("1.85:1"); + _source_ar_combobox->addItem("2.21:1"); + _source_ar_combobox->addItem("2.35:1"); + _source_ar_combobox->addItem("2.39:1"); + _source_ar_combobox->addItem("5:3"); + _source_ar_combobox->addItem("4:3"); + _source_ar_combobox->addItem("5:4"); + _source_ar_combobox->addItem("1:1"); + connect(_source_ar_combobox, SIGNAL(currentIndexChanged(int)), this, SLOT(source_ar_changed())); + QLabel *p_label = new QLabel(_("Parallax:")); p_label->setToolTip(_("

Adjust parallax, from -1 to +1. This changes the separation of left and right view, " "and thus the perceived distance of the scene.

")); @@ -2009,16 +2026,18 @@ video_dialog::video_dialog(QWidget *parent) : QDialog(parent), _lock(false) QGridLayout *layout = new QGridLayout; layout->addWidget(crop_ar_label, 0, 0); layout->addWidget(_crop_ar_combobox, 0, 1, 1, 2); - layout->addWidget(p_label, 1, 0); - layout->addWidget(_p_slider, 1, 1); - layout->addWidget(_p_spinbox, 1, 2); - layout->addWidget(sp_label, 2, 0); - layout->addWidget(_sp_slider, 2, 1); - layout->addWidget(_sp_spinbox, 2, 2); - layout->addWidget(g_label, 3, 0); - layout->addWidget(_g_slider, 3, 1); - layout->addWidget(_g_spinbox, 3, 2); - layout->addWidget(ok_button, 4, 0, 1, 3); + layout->addWidget(source_ar_label, 1, 0); + layout->addWidget(_source_ar_combobox, 1, 1, 1, 2); + layout->addWidget(p_label, 2, 0); + layout->addWidget(_p_slider, 2, 1); + layout->addWidget(_p_spinbox, 2, 2); + layout->addWidget(sp_label, 3, 0); + layout->addWidget(_sp_slider, 3, 1); + layout->addWidget(_sp_spinbox, 3, 2); + layout->addWidget(g_label, 4, 0); + layout->addWidget(_g_slider, 4, 1); + layout->addWidget(_g_spinbox, 4, 2); + layout->addWidget(ok_button, 5, 0, 1, 3); setLayout(layout); update(); @@ -2074,6 +2093,43 @@ void video_dialog::crop_ar_changed() } } +void video_dialog::set_source_ar(float value) +{ + _source_ar_combobox->setCurrentIndex( + ( std::abs(value - 16.0f / 10.0f) < 0.01f ? 1 + : std::abs(value - 16.0f / 9.0f) < 0.01f ? 2 + : std::abs(value - 1.85f) < 0.01f ? 3 + : std::abs(value - 2.21f) < 0.01f ? 4 + : std::abs(value - 2.35f) < 0.01f ? 5 + : std::abs(value - 2.39f) < 0.01f ? 6 + : std::abs(value - 5.0f / 3.0f) < 0.01f ? 7 + : std::abs(value - 4.0f / 3.0f) < 0.01f ? 8 + : std::abs(value - 5.0f / 4.0f) < 0.01f ? 9 + : std::abs(value - 1.0f) < 0.01f ? 10 + : 0)); +} + +void video_dialog::source_ar_changed() +{ + if (!_lock) + { + int i = _source_ar_combobox->currentIndex(); + float ar = + i == 1 ? 16.0f / 10.0f + : i == 2 ? 16.0f / 9.0f + : i == 3 ? 1.85f + : i == 4 ? 2.21f + : i == 5 ? 2.35f + : i == 6 ? 2.39f + : i == 7 ? 5.0f / 3.0f + : i == 8 ? 4.0f / 3.0f + : i == 9 ? 5.0f / 4.0f + : i == 10 ? 1.0f + : 0.0f; + send_cmd(command::set_source_aspect_ratio, ar); + } +} + void video_dialog::p_slider_changed(int val) { if (!_lock) @@ -2115,6 +2171,7 @@ void video_dialog::receive_notification(const notification ¬e) switch (note.type) { case notification::crop_aspect_ratio: + case notification::source_aspect_ratio: case notification::parallax: case notification::subtitle_parallax: case notification::ghostbust: @@ -3350,6 +3407,8 @@ void main_window::open(QStringList filenames, input_data.params.set_stereo_layout_swap(initial_params.stereo_layout_swap()); if (initial_params.crop_aspect_ratio_is_set()) input_data.params.set_crop_aspect_ratio(initial_params.crop_aspect_ratio()); + if (initial_params.source_aspect_ratio_is_set()) + input_data.params.set_source_aspect_ratio(initial_params.source_aspect_ratio()); if (initial_params.parallax_is_set()) input_data.params.set_parallax(initial_params.parallax()); if (initial_params.ghostbust_is_set()) diff --git a/src/gui.h b/src/gui.h index 9fdbe8c..a686cf3 100644 --- a/src/gui.h +++ b/src/gui.h @@ -316,6 +316,7 @@ class video_dialog : public QDialog, public controller private: bool _lock; QComboBox *_crop_ar_combobox; + QComboBox *_source_ar_combobox; QDoubleSpinBox *_p_spinbox; QSlider *_p_slider; QDoubleSpinBox *_sp_spinbox; @@ -324,9 +325,11 @@ private: QSlider *_g_slider; void set_crop_ar(float val); + void set_source_ar(float val); private slots: void crop_ar_changed(); + void source_ar_changed(); void p_slider_changed(int val); void p_spinbox_changed(double val); void sp_slider_changed(int val); diff --git a/src/media_data.cpp b/src/media_data.cpp index 127185d..f4c1cb5 100644 --- a/src/media_data.cpp +++ b/src/media_data.cpp @@ -120,6 +120,7 @@ parameters::parameters() unset_stereo_layout(); unset_stereo_layout_swap(); unset_crop_aspect_ratio(); + unset_source_aspect_ratio(); unset_parallax(); unset_ghostbust(); unset_subtitle_parallax(); @@ -174,6 +175,7 @@ const int parameters::_subtitle_stream_default = -1; const parameters::stereo_layout_t parameters::_stereo_layout_default = layout_mono; const bool parameters::_stereo_layout_swap_default = false; const float parameters::_crop_aspect_ratio_default = 0.0f; +const float parameters::_source_aspect_ratio_default = 0.0f; const float parameters::_parallax_default = 0.0f; const float parameters::_ghostbust_default = 0.0f; const float parameters::_subtitle_parallax_default = 0.0f; @@ -564,6 +566,8 @@ void parameters::save(std::ostream &os) const s11n::save(os, _stereo_layout_swap_set); s11n::save(os, _crop_aspect_ratio); s11n::save(os, _crop_aspect_ratio_set); + s11n::save(os, _source_aspect_ratio); + s11n::save(os, _source_aspect_ratio_set); s11n::save(os, _parallax); s11n::save(os, _parallax_set); s11n::save(os, _ghostbust); @@ -667,6 +671,8 @@ void parameters::load(std::istream &is) s11n::load(is, _stereo_layout_swap_set); s11n::load(is, _crop_aspect_ratio); s11n::load(is, _crop_aspect_ratio_set); + s11n::load(is, _source_aspect_ratio); + s11n::load(is, _source_aspect_ratio_set); s11n::load(is, _parallax); s11n::load(is, _parallax_set); s11n::load(is, _ghostbust); @@ -868,6 +874,7 @@ void parameters::unset_video_parameters() unset_stereo_layout(); unset_stereo_layout_swap(); unset_crop_aspect_ratio(); + unset_source_aspect_ratio(); unset_parallax(); unset_ghostbust(); unset_subtitle_parallax(); @@ -886,6 +893,8 @@ std::string parameters::save_video_parameters() const s11n::save(oss, "stereo_layout", stereo_layout_to_string(stereo_layout(), stereo_layout_swap())); if (!crop_aspect_ratio_is_default()) s11n::save(oss, "crop_aspect_ratio", _crop_aspect_ratio); + if (!source_aspect_ratio_is_default()) + s11n::save(oss, "source_aspect_ratio", _source_aspect_ratio); if (!parallax_is_default()) s11n::save(oss, "parallax", _parallax); if (!ghostbust_is_default()) @@ -919,6 +928,9 @@ void parameters::load_video_parameters(const std::string &s) } else if (name == "crop_aspect_ratio") { s11n::load(value, _crop_aspect_ratio); _crop_aspect_ratio_set = true; + } else if (name == "source_aspect_ratio") { + s11n::load(value, _source_aspect_ratio); + _source_aspect_ratio_set = true; } else if (name == "parallax") { s11n::load(value, _parallax); _parallax_set = true; diff --git a/src/media_data.h b/src/media_data.h index a10b084..706027e 100644 --- a/src/media_data.h +++ b/src/media_data.h @@ -200,6 +200,7 @@ public: PARAMETER(stereo_layout_t, stereo_layout) // Assume this stereo layout PARAMETER(bool, stereo_layout_swap) // Assume this stereo layout PARAMETER(float, crop_aspect_ratio) // Crop the video to this aspect ratio, 0 = don't crop. + PARAMETER(float, source_aspect_ratio) // Force video source to this aspect ratio, 0 = don't force. PARAMETER(float, parallax) // Parallax adjustment, -1 .. +1 PARAMETER(float, ghostbust) // Amount of crosstalk ghostbusting, 0 .. 1 PARAMETER(float, subtitle_parallax) // Subtitle parallax adjustment, -1 .. +1 diff --git a/src/video_output.cpp b/src/video_output.cpp index b53a1b0..92a7b85 100644 --- a/src/video_output.cpp +++ b/src/video_output.cpp @@ -1088,6 +1088,8 @@ void video_output::reshape(int w, int h, const parameters& params) src_ar /= 2.0f; crop_ar /= 2.0f; } + if (params.source_aspect_ratio_is_set()) + src_ar = params.source_aspect_ratio(); compute_viewport_and_tex_coords(_viewport[0], _tex_coords[0], src_ar, w / 2, h, dst_w, dst_h, dst_ar, crop_ar, params.zoom(), need_even_width, need_even_height); @@ -1105,6 +1107,8 @@ void video_output::reshape(int w, int h, const parameters& params) src_ar *= 2.0f; crop_ar *= 2.0f; } + if (params.source_aspect_ratio_is_set()) + src_ar = params.source_aspect_ratio(); compute_viewport_and_tex_coords(_viewport[0], _tex_coords[0], src_ar, w, h / 2, dst_w, dst_h, dst_ar, crop_ar, params.zoom(), need_even_width, need_even_height); @@ -1124,6 +1128,8 @@ void video_output::reshape(int w, int h, const parameters& params) float dst_h = (h - blank_lines) / 2; float dst_ar = dst_w * screen_pixel_aspect_ratio() / dst_h; float src_ar = _frame[_active_index].aspect_ratio; + if (params.source_aspect_ratio_is_set()) + src_ar = params.source_aspect_ratio(); compute_viewport_and_tex_coords(_viewport[0], _tex_coords[0], src_ar, w, (h - blank_lines) / 2, dst_w, dst_h, dst_ar, params.crop_aspect_ratio(), params.zoom(), need_even_width, need_even_height); @@ -1135,6 +1141,8 @@ void video_output::reshape(int w, int h, const parameters& params) float dst_h = h; float dst_ar = dst_w * screen_pixel_aspect_ratio() / dst_h; float src_ar = _frame[_active_index].aspect_ratio; + if (params.source_aspect_ratio_is_set()) + src_ar = params.source_aspect_ratio(); compute_viewport_and_tex_coords(_viewport[0], _tex_coords[0], src_ar, w, h, dst_w, dst_h, dst_ar, params.crop_aspect_ratio(), params.zoom(), need_even_width, need_even_height); @@ -1183,6 +1191,8 @@ void video_output::display_current_frame( || _render_last_params.stereo_mode() != _render_params.stereo_mode() || _render_last_params.crop_aspect_ratio() < _render_params.crop_aspect_ratio() || _render_last_params.crop_aspect_ratio() > _render_params.crop_aspect_ratio() + || _render_last_params.source_aspect_ratio() < _render_params.source_aspect_ratio() + || _render_last_params.source_aspect_ratio() > _render_params.source_aspect_ratio() || _render_last_params.zoom() < _render_params.zoom() || _render_last_params.zoom() > _render_params.zoom() || full_display_width() != dst_width