1
// Copyright (c) 2014, Thomas Goyne <plorkyeran@aegisub.org>
3
// Permission to use, copy, modify, and distribute this software for any
4
// purpose with or without fee is hereby granted, provided that the above
5
// copyright notice and this permission notice appear in all copies.
7
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
// Aegisub Project http://www.aegisub.org/
18
#include "async_video_provider.h"
20
#include "help_button.h"
22
#include "resolution_resampler.h"
24
#include <wx/dialog.h>
26
#include <wx/radiobox.h>
28
#include <wx/stattext.h>
43
int prompt(wxWindow *parent, bool ar_changed, int sx, int sy, int vx, int vy) {
44
wxDialog d(parent, -1, _("Resolution mismatch"));
46
auto label_text = fmt_tl("The resolution of the loaded video and the resolution specified for the subtitles don't match.\n\nVideo resolution:\t%d x %d\nScript resolution:\t%d x %d\n\nChange subtitles resolution to match video?", vx, vy, sx, sy);
48
auto sizer = new wxBoxSizer(wxVERTICAL);
49
sizer->Add(new wxStaticText(&d, -1, label_text), wxSizerFlags().Border());
53
wxString choices[] = {
54
_("Set to video resolution"),
55
_("Resample script (stretch to new aspect ratio)"),
56
_("Resample script (add borders)"),
57
_("Resample script (remove borders)")
59
rb = new wxRadioBox(&d, -1, "", wxDefaultPosition, wxDefaultSize, 4, choices, 1);
62
wxString choices[] = {
63
_("Set to video resolution"),
66
rb = new wxRadioBox(&d, -1, "", wxDefaultPosition, wxDefaultSize, 2, choices, 1);
68
sizer->Add(rb, wxSizerFlags().Border(wxALL & ~wxTOP).Expand());
69
sizer->Add(d.CreateStdDialogButtonSizer(wxOK | wxCANCEL | wxHELP), wxSizerFlags().Border().Expand());
71
unsigned int sel = OPT_GET("Video/Last Script Resolution Mismatch Choice")->GetInt();
72
rb->SetSelection(std::min(sel - 1, rb->GetCount()));
74
d.SetSizerAndFit(sizer);
77
d.Bind(wxEVT_BUTTON, [&](wxCommandEvent&) { d.EndModal(rb->GetSelection() + 1); }, wxID_OK);
78
d.Bind(wxEVT_BUTTON, [&](wxCommandEvent&) { d.EndModal(0); }, wxID_CANCEL);
79
d.Bind(wxEVT_BUTTON, [&](wxCommandEvent&) { HelpButton::OpenPage("Resolution mismatch"); }, wxID_HELP);
84
bool update_video_properties(AssFile *file, const AsyncVideoProvider *new_provider, wxWindow *parent) {
85
bool commit_subs = false;
87
// When opening dummy video only want to set the script properties if
88
// they were previously unset
89
bool set_properties = new_provider->ShouldSetVideoProperties();
91
auto matrix = new_provider->GetColorSpace();
92
if (set_properties && matrix != file->GetScriptInfo("YCbCr Matrix")) {
93
file->SetScriptInfo("YCbCr Matrix", matrix);
97
// Check that the script resolution matches the video resolution
98
int sx = file->GetScriptInfoAsInt("PlayResX");
99
int sy = file->GetScriptInfoAsInt("PlayResY");
100
int vx = new_provider->GetWidth();
101
int vy = new_provider->GetHeight();
103
// If the script resolution hasn't been set at all just force it to the
105
if (sx == 0 && sy == 0) {
106
file->SetScriptInfo("PlayResX", std::to_string(vx));
107
file->SetScriptInfo("PlayResY", std::to_string(vy));
114
// Treat exact multiples of the video resolution as equaling the resolution
115
// for the people who use that for subpixel precision (which is mostly
116
// pointless these days due to decimals being supported almost everywhere)
117
if (sx % vx == 0 && sy % vy == 0)
120
auto sar = double(sx) / sy;
121
auto var = double(vx) / vy;
122
bool ar_changed = abs(sar - var) / var > .01;
124
switch (OPT_GET("Video/Script Resolution Mismatch")->GetInt()) {
125
case MISMATCH_IGNORE: default:
129
file->SetScriptInfo("PlayResX", std::to_string(vx));
130
file->SetScriptInfo("PlayResY", std::to_string(vy));
133
case MISMATCH_RESAMPLE:
134
// Fallthrough to prompt if the AR changed
136
ResampleResolution(file, {
139
ResampleARMode::Stretch,
140
YCbCrMatrix::rgb, YCbCrMatrix::rgb
145
case MISMATCH_PROMPT:
146
int res = prompt(parent, ar_changed, sx, sy, vx, vy);
147
if (res == FIX_IGNORE) return commit_subs;
148
OPT_SET("Video/Last Script Resolution Mismatch Choice")->SetInt(res);
150
ResampleResolution(file, {
153
static_cast<ResampleARMode>(res - FIX_RESAMPLE),
154
YCbCrMatrix::rgb, YCbCrMatrix::rgb
161
void UpdateVideoProperties(AssFile *file, const AsyncVideoProvider *new_provider, wxWindow *parent) {
162
if (update_video_properties(file, new_provider, parent))
163
file->Commit(_("change script resolution"), AssFile::COMMIT_SCRIPTINFO);