forked from mia/Aegisub
Add an option to resample the script to the resolution mismatch dialog
Closes #1382.
This commit is contained in:
parent
32fae528b0
commit
d0ce26d7df
9 changed files with 199 additions and 52 deletions
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<!-- VC boilerplate -->
|
<!-- VC boilerplate -->
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
|
@ -173,6 +173,7 @@
|
||||||
<ClInclude Include="$(SrcDir)dialog_translation.h" />
|
<ClInclude Include="$(SrcDir)dialog_translation.h" />
|
||||||
<ClInclude Include="$(SrcDir)dialog_version_check.h" />
|
<ClInclude Include="$(SrcDir)dialog_version_check.h" />
|
||||||
<ClInclude Include="$(SrcDir)dialog_video_details.h" />
|
<ClInclude Include="$(SrcDir)dialog_video_details.h" />
|
||||||
|
<ClInclude Include="$(SrcDir)dialog_video_properties.h" />
|
||||||
<ClInclude Include="$(SrcDir)export_fixstyle.h" />
|
<ClInclude Include="$(SrcDir)export_fixstyle.h" />
|
||||||
<ClInclude Include="$(SrcDir)export_framerate.h" />
|
<ClInclude Include="$(SrcDir)export_framerate.h" />
|
||||||
<ClInclude Include="$(SrcDir)factory_manager.h" />
|
<ClInclude Include="$(SrcDir)factory_manager.h" />
|
||||||
|
@ -370,6 +371,7 @@
|
||||||
<ClCompile Include="$(SrcDir)dialog_translation.cpp" />
|
<ClCompile Include="$(SrcDir)dialog_translation.cpp" />
|
||||||
<ClCompile Include="$(SrcDir)dialog_version_check.cpp" />
|
<ClCompile Include="$(SrcDir)dialog_version_check.cpp" />
|
||||||
<ClCompile Include="$(SrcDir)dialog_video_details.cpp" />
|
<ClCompile Include="$(SrcDir)dialog_video_details.cpp" />
|
||||||
|
<ClCompile Include="$(SrcDir)dialog_video_properties.cpp" />
|
||||||
<ClCompile Include="$(SrcDir)export_fixstyle.cpp" />
|
<ClCompile Include="$(SrcDir)export_fixstyle.cpp" />
|
||||||
<ClCompile Include="$(SrcDir)export_framerate.cpp" />
|
<ClCompile Include="$(SrcDir)export_framerate.cpp" />
|
||||||
<ClCompile Include="$(SrcDir)ffmpegsource_common.cpp">
|
<ClCompile Include="$(SrcDir)ffmpegsource_common.cpp">
|
||||||
|
|
|
@ -621,6 +621,9 @@
|
||||||
<ClInclude Include="$(SrcDir)subtitle_format_ssa.h">
|
<ClInclude Include="$(SrcDir)subtitle_format_ssa.h">
|
||||||
<Filter>Subtitle formats</Filter>
|
<Filter>Subtitle formats</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="$(SrcDir)dialog_video_properties.h">
|
||||||
|
<Filter>Features\Resolution resampler</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="$(SrcDir)ass_dialogue.cpp">
|
<ClCompile Include="$(SrcDir)ass_dialogue.cpp">
|
||||||
|
@ -1175,9 +1178,12 @@
|
||||||
<ClCompile Include="$(SrcDir)subtitle_format_ssa.cpp">
|
<ClCompile Include="$(SrcDir)subtitle_format_ssa.cpp">
|
||||||
<Filter>Subtitle formats</Filter>
|
<Filter>Subtitle formats</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="$(SrcDir)dialog_video_properties.cpp">
|
||||||
|
<Filter>Features\Resolution resampler</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="$(SrcDir)res\res.rc" />
|
<ResourceCompile Include="$(SrcDir)res\res.rc" />
|
||||||
<ResourceCompile Include="$(SrcDir)res\strings.rc" />
|
<ResourceCompile Include="$(SrcDir)res\strings.rc" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -184,6 +184,7 @@ SRC += \
|
||||||
dialog_translation.cpp \
|
dialog_translation.cpp \
|
||||||
dialog_version_check.cpp \
|
dialog_version_check.cpp \
|
||||||
dialog_video_details.cpp \
|
dialog_video_details.cpp \
|
||||||
|
dialog_video_properties.cpp \
|
||||||
export_fixstyle.cpp \
|
export_fixstyle.cpp \
|
||||||
export_framerate.cpp \
|
export_framerate.cpp \
|
||||||
fft.cpp \
|
fft.cpp \
|
||||||
|
|
156
src/dialog_video_properties.cpp
Normal file
156
src/dialog_video_properties.cpp
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
// Copyright (c) 2014, Thomas Goyne <plorkyeran@aegisub.org>
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
//
|
||||||
|
// Aegisub Project http://www.aegisub.org/
|
||||||
|
|
||||||
|
#include "dialog_video_properties.h"
|
||||||
|
|
||||||
|
#include "ass_file.h"
|
||||||
|
#include "include/aegisub/video_provider.h"
|
||||||
|
#include "options.h"
|
||||||
|
#include "resolution_resampler.h"
|
||||||
|
|
||||||
|
#include <wx/dialog.h>
|
||||||
|
#include <wx/radiobox.h>
|
||||||
|
#include <wx/sizer.h>
|
||||||
|
#include <wx/stattext.h>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
enum {
|
||||||
|
MISMATCH_IGNORE,
|
||||||
|
MISMATCH_PROMPT,
|
||||||
|
MISMATCH_RESAMPLE,
|
||||||
|
MISMATCH_SET
|
||||||
|
};
|
||||||
|
enum {
|
||||||
|
FIX_IGNORE,
|
||||||
|
FIX_SET,
|
||||||
|
FIX_RESAMPLE
|
||||||
|
};
|
||||||
|
|
||||||
|
class Prompt : public wxDialog {
|
||||||
|
public:
|
||||||
|
Prompt(wxWindow *parent, bool ar_changed, int sx, int sy, int vx, int vy)
|
||||||
|
: wxDialog(parent, -1, _("Resolution mismatch"))
|
||||||
|
{
|
||||||
|
auto label_text = wxString::Format(_("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);
|
||||||
|
|
||||||
|
auto sizer = new wxBoxSizer(wxVERTICAL);
|
||||||
|
sizer->Add(new wxStaticText(this, -1, label_text), wxSizerFlags().Border());
|
||||||
|
|
||||||
|
wxRadioBox *rb;
|
||||||
|
if (ar_changed) {
|
||||||
|
wxString choices[] = {
|
||||||
|
_("Set to video resolution"),
|
||||||
|
_("Resample script (stretch to new aspect ratio)"),
|
||||||
|
_("Resample script (add borders)"),
|
||||||
|
_("Resample script (remove borders)")
|
||||||
|
};
|
||||||
|
rb = new wxRadioBox(this, -1, "", wxDefaultPosition, wxDefaultSize, 4, choices, 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wxString choices[] = {
|
||||||
|
_("Set to video resolution"),
|
||||||
|
_("Resample script"),
|
||||||
|
};
|
||||||
|
rb = new wxRadioBox(this, -1, "", wxDefaultPosition, wxDefaultSize, 2, choices, 1);
|
||||||
|
}
|
||||||
|
sizer->Add(rb, wxSizerFlags().Border(wxALL & ~wxTOP).Expand());
|
||||||
|
sizer->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL | wxHELP), wxSizerFlags().Border().Expand());
|
||||||
|
|
||||||
|
unsigned int sel = OPT_GET("Video/Last Script Resolution Mismatch Choice")->GetInt();
|
||||||
|
rb->SetSelection(std::min(sel - 1, rb->GetCount()));
|
||||||
|
|
||||||
|
SetSizerAndFit(sizer);
|
||||||
|
CenterOnParent();
|
||||||
|
|
||||||
|
Bind(wxEVT_BUTTON, [=](wxCommandEvent&) { EndModal(rb->GetSelection() + 1); }, wxID_OK);
|
||||||
|
Bind(wxEVT_BUTTON, [=](wxCommandEvent&) { EndModal(0); }, wxID_CANCEL);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UpdateVideoProperties(AssFile *file, const VideoProvider *new_provider, wxWindow *parent) {
|
||||||
|
bool commit_subs = false;
|
||||||
|
|
||||||
|
// When opening dummy video only want to set the script properties if
|
||||||
|
// they were previously unset
|
||||||
|
bool set_properties = new_provider->ShouldSetVideoProperties();
|
||||||
|
|
||||||
|
auto matrix = new_provider->GetColorSpace();
|
||||||
|
if (set_properties && matrix != file->GetScriptInfo("YCbCr Matrix")) {
|
||||||
|
file->SetScriptInfo("YCbCr Matrix", matrix);
|
||||||
|
commit_subs = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that the script resolution matches the video resolution
|
||||||
|
int sx = file->GetScriptInfoAsInt("PlayResX");
|
||||||
|
int sy = file->GetScriptInfoAsInt("PlayResY");
|
||||||
|
int vx = new_provider->GetWidth();
|
||||||
|
int vy = new_provider->GetHeight();
|
||||||
|
|
||||||
|
// If the script resolution hasn't been set at all just force it to the
|
||||||
|
// video resolution
|
||||||
|
if (sx == 0 && sy == 0) {
|
||||||
|
file->SetScriptInfo("PlayResX", std::to_string(vx));
|
||||||
|
file->SetScriptInfo("PlayResY", std::to_string(vy));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!set_properties)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Treat exact multiples of the video resolution as equaling the resolution
|
||||||
|
// for the people who use that for subpixel precision (which is mostly
|
||||||
|
// pointless these days due to decimals being supported almost everywhere)
|
||||||
|
if (sx % vx == 0 && sy % vy == 0)
|
||||||
|
return commit_subs;
|
||||||
|
|
||||||
|
auto sar = double(sx) / sy;
|
||||||
|
auto var = double(vx) / vy;
|
||||||
|
bool ar_changed = abs(sar - var) / var > .01;
|
||||||
|
|
||||||
|
switch (OPT_GET("Video/Script Resolution Mismatch")->GetInt()) {
|
||||||
|
case MISMATCH_IGNORE: default:
|
||||||
|
return commit_subs;
|
||||||
|
|
||||||
|
case MISMATCH_SET:
|
||||||
|
file->SetScriptInfo("PlayResX", std::to_string(vx));
|
||||||
|
file->SetScriptInfo("PlayResY", std::to_string(vy));
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case MISMATCH_RESAMPLE:
|
||||||
|
// Fallthrough to prompt if the AR changed
|
||||||
|
if (!ar_changed) {
|
||||||
|
ResampleResolution(file, {
|
||||||
|
{0, 0, 0, 0},
|
||||||
|
sx, sy, vx, vy,
|
||||||
|
ResampleARMode::Stretch
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MISMATCH_PROMPT:
|
||||||
|
int res = Prompt(parent, ar_changed, sx, sy, vx, vy).ShowModal();
|
||||||
|
if (res == FIX_IGNORE) return commit_subs;
|
||||||
|
OPT_SET("Video/Last Script Resolution Mismatch Choice")->SetInt(res);
|
||||||
|
|
||||||
|
ResampleResolution(file, {
|
||||||
|
{0, 0, 0, 0},
|
||||||
|
sx, sy, vx, vy,
|
||||||
|
static_cast<ResampleARMode>(res - FIX_RESAMPLE)
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
23
src/dialog_video_properties.h
Normal file
23
src/dialog_video_properties.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// Copyright (c) 2014, Thomas Goyne <plorkyeran@aegisub.org>
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
//
|
||||||
|
// Aegisub Project http://www.aegisub.org/
|
||||||
|
|
||||||
|
class AssFile;
|
||||||
|
class VideoProvider;
|
||||||
|
class wxWindow;
|
||||||
|
|
||||||
|
/// Update the video properties for a newly opened video, possibly prompting the user about what to do
|
||||||
|
/// @return Does the file need to be committed?
|
||||||
|
bool UpdateVideoProperties(AssFile *file, const VideoProvider *new_provider, wxWindow *parent);
|
|
@ -572,7 +572,6 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
"Video" : {
|
"Video" : {
|
||||||
"Check Script Res" : 1,
|
|
||||||
"Default Zoom" : 7,
|
"Default Zoom" : 7,
|
||||||
"Detached" : {
|
"Detached" : {
|
||||||
"Enabled" : false,
|
"Enabled" : false,
|
||||||
|
@ -592,9 +591,11 @@
|
||||||
"Pattern" : false
|
"Pattern" : false
|
||||||
},
|
},
|
||||||
"Force BT.601" : true,
|
"Force BT.601" : true,
|
||||||
|
"Last Script Resolution Mismatch Choice" : 2,
|
||||||
"Open Audio" : false,
|
"Open Audio" : false,
|
||||||
"Overscan Mask" : false,
|
"Overscan Mask" : false,
|
||||||
"Provider" : "ffmpegsource",
|
"Provider" : "ffmpegsource",
|
||||||
|
"Script Resolution Mismatch" : 1,
|
||||||
"Slider" : {
|
"Slider" : {
|
||||||
"Fast Jump Step" : 10,
|
"Fast Jump Step" : 10,
|
||||||
"Show Keyframes" : true
|
"Show Keyframes" : true
|
||||||
|
|
|
@ -572,7 +572,6 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
"Video" : {
|
"Video" : {
|
||||||
"Check Script Res" : 1,
|
|
||||||
"Default Zoom" : 7,
|
"Default Zoom" : 7,
|
||||||
"Detached" : {
|
"Detached" : {
|
||||||
"Enabled" : false,
|
"Enabled" : false,
|
||||||
|
@ -592,9 +591,11 @@
|
||||||
"Pattern" : false
|
"Pattern" : false
|
||||||
},
|
},
|
||||||
"Force BT.601" : true,
|
"Force BT.601" : true,
|
||||||
|
"Last Script Resolution Mismatch Choice" : 2,
|
||||||
"Open Audio" : false,
|
"Open Audio" : false,
|
||||||
"Overscan Mask" : false,
|
"Overscan Mask" : false,
|
||||||
"Provider" : "ffmpegsource",
|
"Provider" : "ffmpegsource",
|
||||||
|
"Script Resolution Mismatch" : 1,
|
||||||
"Slider" : {
|
"Slider" : {
|
||||||
"Fast Jump Step" : 10,
|
"Fast Jump Step" : 10,
|
||||||
"Show Keyframes" : true
|
"Show Keyframes" : true
|
||||||
|
|
|
@ -220,9 +220,9 @@ Video::Video(wxTreebook *book, Preferences *parent): OptionPage(book, parent, _(
|
||||||
DisableIfChecked(autocb,
|
DisableIfChecked(autocb,
|
||||||
OptionAdd(resolution, _("Default height"), "Subtitle/Default Resolution/Height"));
|
OptionAdd(resolution, _("Default height"), "Subtitle/Default Resolution/Height"));
|
||||||
|
|
||||||
const wxString cres_arr[3] = { _("Never"), _("Ask"), _("Always") };
|
const wxString cres_arr[] = {_("Never"), _("Ask"), _("Always set"), _("Always resample")};
|
||||||
wxArrayString choice_res(3, cres_arr);
|
wxArrayString choice_res(4, cres_arr);
|
||||||
OptionChoice(resolution, _("Match video resolution on open"), choice_res, "Video/Check Script Res");
|
OptionChoice(resolution, _("Match video resolution on open"), choice_res, "Video/Script Resolution Mismatch");
|
||||||
|
|
||||||
SetSizerAndFit(sizer);
|
SetSizerAndFit(sizer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "audio_controller.h"
|
#include "audio_controller.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "dialog_progress.h"
|
#include "dialog_progress.h"
|
||||||
|
#include "dialog_video_properties.h"
|
||||||
#include "include/aegisub/context.h"
|
#include "include/aegisub/context.h"
|
||||||
#include "include/aegisub/video_provider.h"
|
#include "include/aegisub/video_provider.h"
|
||||||
#include "mkv_wrap.h"
|
#include "mkv_wrap.h"
|
||||||
|
@ -121,51 +122,7 @@ void VideoContext::SetVideo(const agi::fs::path &filename) {
|
||||||
video_provider = provider->GetVideoProvider();
|
video_provider = provider->GetVideoProvider();
|
||||||
video_filename = filename;
|
video_filename = filename;
|
||||||
|
|
||||||
// When opening dummy video only want to set the script properties if
|
bool needs_commit = UpdateVideoProperties(context->ass.get(), video_provider, context->parent);
|
||||||
// they were previously unset
|
|
||||||
bool set_properties = video_provider->ShouldSetVideoProperties();
|
|
||||||
|
|
||||||
auto matrix = video_provider->GetColorSpace();
|
|
||||||
if (set_properties && matrix != old_matrix) {
|
|
||||||
context->ass->SetScriptInfo("YCbCr Matrix", matrix);
|
|
||||||
commit_subs = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that the script resolution matches the video resolution
|
|
||||||
int sx = context->ass->GetScriptInfoAsInt("PlayResX");
|
|
||||||
int sy = context->ass->GetScriptInfoAsInt("PlayResY");
|
|
||||||
int vx = GetWidth();
|
|
||||||
int vy = GetHeight();
|
|
||||||
|
|
||||||
// If the script resolution hasn't been set at all just force it to the
|
|
||||||
// video resolution
|
|
||||||
if (sx == 0 && sy == 0) {
|
|
||||||
context->ass->SetScriptInfo("PlayResX", std::to_string(vx));
|
|
||||||
context->ass->SetScriptInfo("PlayResY", std::to_string(vy));
|
|
||||||
commit_subs = true;
|
|
||||||
}
|
|
||||||
// If it has been set to something other than a multiple of the video
|
|
||||||
// resolution, ask the user if they want it to be fixed
|
|
||||||
else if (set_properties && (sx % vx != 0 || sy % vy != 0)) {
|
|
||||||
switch (OPT_GET("Video/Check Script Res")->GetInt()) {
|
|
||||||
case 1: // Ask to change on mismatch
|
|
||||||
if (wxYES != wxMessageBox(
|
|
||||||
wxString::Format(_("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),
|
|
||||||
_("Resolution mismatch"),
|
|
||||||
wxYES_NO | wxCENTER,
|
|
||||||
context->parent))
|
|
||||||
|
|
||||||
break;
|
|
||||||
// Fallthrough to case 2
|
|
||||||
case 2: // Always change script res
|
|
||||||
context->ass->SetScriptInfo("PlayResX", std::to_string(vx));
|
|
||||||
context->ass->SetScriptInfo("PlayResY", std::to_string(vy));
|
|
||||||
commit_subs = true;
|
|
||||||
break;
|
|
||||||
default: // Never change
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
keyframes = video_provider->GetKeyFrames();
|
keyframes = video_provider->GetKeyFrames();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue