From bc74dfc33b5a72bc9d56000f13fd49ec6558863a Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Fri, 11 May 2012 14:38:44 +0000 Subject: [PATCH] Update the video matrix tagging scheme Write the color range and color space used to convert video to RGB to the YCbCr Matrix field, or None if no non-RGB video was opened. See http://code.google.com/p/xy-vsfilter/issues/detail?id=91 for related discussion. Originally committed to SVN as r6762. --- aegisub/automation/autoload/clean-info.lua | 1 + aegisub/src/ass_file.cpp | 1 + aegisub/src/include/aegisub/video_provider.h | 4 +-- aegisub/src/video_context.cpp | 3 +- aegisub/src/video_provider_avs.cpp | 11 +++---- aegisub/src/video_provider_dummy.h | 3 +- aegisub/src/video_provider_ffmpegsource.cpp | 31 ++++++++++++++++---- aegisub/src/video_provider_yuv4mpeg.h | 7 +++-- 8 files changed, 41 insertions(+), 20 deletions(-) diff --git a/aegisub/automation/autoload/clean-info.lua b/aegisub/automation/autoload/clean-info.lua index 2f9f88862..48839b428 100644 --- a/aegisub/automation/autoload/clean-info.lua +++ b/aegisub/automation/autoload/clean-info.lua @@ -29,6 +29,7 @@ function clean_script_info(subs) ["scaledborderandshadow"] = true, ["scripttype"] = true, ["video colorspace"] = true, + ["ycbcr matrix"] = true, ["wrapstyle"] = true } diff --git a/aegisub/src/ass_file.cpp b/aegisub/src/ass_file.cpp index 661b0423e..dabe3863a 100644 --- a/aegisub/src/ass_file.cpp +++ b/aegisub/src/ass_file.cpp @@ -378,6 +378,7 @@ void AssFile::LoadDefault(bool defline) { AddLine(wxString::Format("PlayResX: %" PRId64, OPT_GET("Subtitle/Default Resolution/Width")->GetInt()), &version, &attach); AddLine(wxString::Format("PlayResY: %" PRId64, OPT_GET("Subtitle/Default Resolution/Height")->GetInt()), &version, &attach); } + AddLine("YCbCr Matrix: None", &version, &attach); InsertStyle(new AssStyle); diff --git a/aegisub/src/include/aegisub/video_provider.h b/aegisub/src/include/aegisub/video_provider.h index 7b6570af4..d6981cd5b 100644 --- a/aegisub/src/include/aegisub/video_provider.h +++ b/aegisub/src/include/aegisub/video_provider.h @@ -65,9 +65,9 @@ public: virtual std::vector GetKeyFrames() const=0;///< Returns list of keyframes /// Get the source colorspace of the video before it was converted to RGB - /// @return A string describing the source colorspace or empty if it is + /// @return A string describing the source colorspace or "None" if it is /// unknown or meaningless - virtual wxString GetColorSpace() const { return ""; } + virtual wxString GetColorSpace() const = 0; /// @brief Use this to set any post-loading warnings, such as "being loaded with unreliable seeking" virtual wxString GetWarning() const { return ""; } diff --git a/aegisub/src/video_context.cpp b/aegisub/src/video_context.cpp index a2f56cd5c..60416d71b 100644 --- a/aegisub/src/video_context.cpp +++ b/aegisub/src/video_context.cpp @@ -250,7 +250,6 @@ void VideoContext::OnSubtitlesCommit() { void VideoContext::OnSubtitlesSave() { if (!IsLoaded()) { context->ass->SetScriptInfo("Video File", ""); - context->ass->SetScriptInfo("Video Colorspace", ""); context->ass->SetScriptInfo("Video Aspect Ratio", ""); context->ass->SetScriptInfo("Video Position", ""); context->ass->SetScriptInfo("VFR File", ""); @@ -265,7 +264,7 @@ void VideoContext::OnSubtitlesSave() { ar = wxString::Format("%d", arType); context->ass->SetScriptInfo("Video File", MakeRelativePath(videoFile, context->ass->filename)); - context->ass->SetScriptInfo("Video Colorspace", videoProvider->GetColorSpace()); + context->ass->SetScriptInfo("YCbCr Matrix", videoProvider->GetColorSpace()); context->ass->SetScriptInfo("Video Aspect Ratio", ar); context->ass->SetScriptInfo("Video Position", wxString::Format("%d", frame_n)); context->ass->SetScriptInfo("VFR File", MakeRelativePath(GetTimecodesName(), context->ass->filename)); diff --git a/aegisub/src/video_provider_avs.cpp b/aegisub/src/video_provider_avs.cpp index 46f367ba2..af4b5a069 100644 --- a/aegisub/src/video_provider_avs.cpp +++ b/aegisub/src/video_provider_avs.cpp @@ -162,18 +162,15 @@ file_exit: AVSValue args[2] = { script, "Rec601" }; if (!OPT_GET("Video/Force BT.601")->GetBool() && (vi.width > 1024 || vi.height >= 600)) { args[1] = "Rec709"; - colorspace = "BT.709"; + colorspace = "TV.709"; } else - colorspace = "BT.601"; + colorspace = "TV.601"; const char *argnames[2] = { 0, "matrix" }; script = avs.GetEnv()->Invoke("ConvertToRGB32", AVSValue(args, 2), argnames); } - else if (extension != ".avs") - colorspace = "RGB"; - // Don't set the colorspace to RGB if we're opening an Avisynth script - // as we can't tell RGB source video apart from a script that happens - // to convert to rgb + else + colorspace = "None"; RGB32Video = avs.GetEnv()->Invoke("Cache", script).AsClip(); vi = RGB32Video->GetVideoInfo(); diff --git a/aegisub/src/video_provider_dummy.h b/aegisub/src/video_provider_dummy.h index c586865c3..841c278d0 100644 --- a/aegisub/src/video_provider_dummy.h +++ b/aegisub/src/video_provider_dummy.h @@ -90,6 +90,7 @@ public: int GetHeight() const { return height; } double GetDAR() const { return 0; } agi::vfr::Framerate GetFPS() const { return fps; } - std::vector GetKeyFrames() const { return std::vector(); }; + std::vector GetKeyFrames() const { return std::vector(); } + wxString GetColorSpace() const { return "None"; } wxString GetDecoderName() const { return "Dummy Video Provider"; } }; diff --git a/aegisub/src/video_provider_ffmpegsource.cpp b/aegisub/src/video_provider_ffmpegsource.cpp index 6847128d4..10ef687d5 100644 --- a/aegisub/src/video_provider_ffmpegsource.cpp +++ b/aegisub/src/video_provider_ffmpegsource.cpp @@ -179,6 +179,9 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) { else DAR = double(Width) / Height; + // Assuming TV for unspecified + wxString ColorRange = TempFrame->ColorRange == FFMS_CR_JPEG ? "PC" : "TV"; + int CS = TempFrame->ColorSpace; #if FFMS_VERSION >= ((2 << 24) | (17 << 16) | (1 << 8) | 0) if (CS != FFMS_CS_RGB && CS != FFMS_CS_BT470BG && OPT_GET("Video/Force BT.601")->GetBool()) { @@ -186,15 +189,33 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) { throw VideoOpenError(std::string("Failed to set input format: ") + ErrInfo.Buffer); CS = FFMS_CS_BT470BG; + ColorRange = "TV"; } #endif switch (CS) { - case FFMS_CS_RGB: ColorSpace = "RGB"; break; - case FFMS_CS_BT709: ColorSpace = "BT.709"; break; - case FFMS_CS_BT470BG: ColorSpace = "BT.601"; break; - case FFMS_CS_UNSPECIFIED: ColorSpace = Width > 1024 || Height >= 600 ? "BT.709" : "BT.601"; break; - default: ColorSpace = ""; break; + case FFMS_CS_RGB: + ColorSpace = "None"; + break; + case FFMS_CS_BT709: + ColorSpace = wxString::Format("%s.709", ColorRange); + break; + case FFMS_CS_UNSPECIFIED: + ColorSpace = wxString::Format("%s.%s", ColorRange, Width > 1024 || Height >= 600 ? "709" : "601"); + break; + case FFMS_CS_FCC: + ColorSpace = wxString::Format("%s.FCC", ColorRange); + break; + case FFMS_CS_BT470BG: + case FFMS_CS_SMPTE170M: + ColorSpace = wxString::Format("%s.601", ColorRange); + break; + case FFMS_CS_SMPTE240M: + ColorSpace = wxString::Format("%s.204M", ColorRange); + break; + default: + throw VideoOpenError("Unknown video color space"); + break; } const int TargetFormat[] = { FFMS_GetPixFmt("bgra"), -1 }; diff --git a/aegisub/src/video_provider_yuv4mpeg.h b/aegisub/src/video_provider_yuv4mpeg.h index 10da124cd..91b19b61d 100644 --- a/aegisub/src/video_provider_yuv4mpeg.h +++ b/aegisub/src/video_provider_yuv4mpeg.h @@ -148,7 +148,8 @@ public: int GetHeight() const { return h; } double GetDAR() const { return 0; } agi::vfr::Framerate GetFPS() const { return fps; } - std::vector GetKeyFrames() const { return std::vector(); }; - wxString GetDecoderName() const { return "YU4MPEG"; }; - bool WantsCaching() const { return true; }; + std::vector GetKeyFrames() const { return std::vector(); } + wxString GetColorSpace() const { return "TV.601"; } + wxString GetDecoderName() const { return "YU4MPEG"; } + bool WantsCaching() const { return true; } };