From 70e7fb28b9ef585868ac91f6d2b89011b27fa46a Mon Sep 17 00:00:00 2001 From: Dave Pusey Date: Thu, 4 Apr 2024 11:17:20 +0100 Subject: [PATCH] Move MKV Bluray parsing from BinEdit.cs into libse for use by third-party code. --- src/libse/BluRaySup/BluRaySupParser.cs | 76 ++++++++++++++++++++++++++ src/ui/Forms/BinaryEdit/BinEdit.cs | 70 +----------------------- 2 files changed, 77 insertions(+), 69 deletions(-) diff --git a/src/libse/BluRaySup/BluRaySupParser.cs b/src/libse/BluRaySup/BluRaySupParser.cs index 5c7056643..c034ca016 100644 --- a/src/libse/BluRaySup/BluRaySupParser.cs +++ b/src/libse/BluRaySup/BluRaySupParser.cs @@ -18,6 +18,7 @@ */ using Nikse.SubtitleEdit.Core.Common; +using Nikse.SubtitleEdit.Core.ContainerFormats.Matroska; using Nikse.SubtitleEdit.Core.Interfaces; using System; using System.Collections.Generic; @@ -399,6 +400,81 @@ namespace Nikse.SubtitleEdit.Core.BluRaySup } } + public static List ParseBluRaySupFromMatroska(MatroskaTrackInfo matroskaSubtitleInfo, MatroskaFile matroska) + { + var sub = matroska.GetSubtitle(matroskaSubtitleInfo.TrackNumber, null); + var subtitles = new List(); + var log = new StringBuilder(); + var clusterStream = new MemoryStream(); + var lastPalettes = new Dictionary>(); + var lastBitmapObjects = new Dictionary>(); + foreach (var p in sub) + { + byte[] buffer = p.GetData(matroskaSubtitleInfo); + if (buffer != null && buffer.Length > 2) + { + clusterStream.Write(buffer, 0, buffer.Length); + if (ContainsBluRayStartSegment(buffer)) + { + if (subtitles.Count > 0 && subtitles[subtitles.Count - 1].StartTime == subtitles[subtitles.Count - 1].EndTime) + { + subtitles[subtitles.Count - 1].EndTime = (long)((p.Start - 1) * 90.0); + } + + clusterStream.Position = 0; + var list = ParseBluRaySup(clusterStream, log, true, lastPalettes, lastBitmapObjects); + foreach (var sup in list) + { + sup.StartTime = (long)((p.Start - 1) * 90.0); + sup.EndTime = (long)((p.End - 1) * 90.0); + subtitles.Add(sup); + + // fix overlapping + if (subtitles.Count > 1 && sub[subtitles.Count - 2].End > sub[subtitles.Count - 1].Start) + { + subtitles[subtitles.Count - 2].EndTime = subtitles[subtitles.Count - 1].StartTime - 1; + } + } + + clusterStream = new MemoryStream(); + } + } + else if (subtitles.Count > 0) + { + var lastSub = subtitles[subtitles.Count - 1]; + if (lastSub.StartTime == lastSub.EndTime) + { + lastSub.EndTime = (long)((p.Start - 1) * 90.0); + if (lastSub.EndTime - lastSub.StartTime > 1000000) + { + lastSub.EndTime = lastSub.StartTime; + } + } + } + } + + return subtitles; + } + + private static bool ContainsBluRayStartSegment(byte[] buffer) + { + const int epochStart = 0x80; + var position = 0; + while (position + 3 <= buffer.Length) + { + var segmentType = buffer[position]; + if (segmentType == epochStart) + { + return true; + } + + var length = BigEndianInt16(buffer, position + 1) + 3; + position += length; + } + + return false; + } + private static SupSegment ParseSegmentHeader(byte[] buffer, StringBuilder log) { var segment = new SupSegment(); diff --git a/src/ui/Forms/BinaryEdit/BinEdit.cs b/src/ui/Forms/BinaryEdit/BinEdit.cs index 8446adddb..e8cf6b1c8 100644 --- a/src/ui/Forms/BinaryEdit/BinEdit.cs +++ b/src/ui/Forms/BinaryEdit/BinEdit.cs @@ -1016,56 +1016,7 @@ namespace Nikse.SubtitleEdit.Forms.BinaryEdit } CleanUp(); - var sub = matroska.GetSubtitle(matroskaSubtitleInfo.TrackNumber, null); - var subtitles = new List(); - var log = new StringBuilder(); - var clusterStream = new MemoryStream(); - var lastPalettes = new Dictionary>(); - var lastBitmapObjects = new Dictionary>(); - foreach (var p in sub) - { - byte[] buffer = p.GetData(matroskaSubtitleInfo); - if (buffer != null && buffer.Length > 2) - { - clusterStream.Write(buffer, 0, buffer.Length); - if (ContainsBluRayStartSegment(buffer)) - { - if (subtitles.Count > 0 && subtitles[subtitles.Count - 1].StartTime == subtitles[subtitles.Count - 1].EndTime) - { - subtitles[subtitles.Count - 1].EndTime = (long)((p.Start - 1) * 90.0); - } - - clusterStream.Position = 0; - var list = BluRaySupParser.ParseBluRaySup(clusterStream, log, true, lastPalettes, lastBitmapObjects); - foreach (var sup in list) - { - sup.StartTime = (long)((p.Start - 1) * 90.0); - sup.EndTime = (long)((p.End - 1) * 90.0); - subtitles.Add(sup); - - // fix overlapping - if (subtitles.Count > 1 && sub[subtitles.Count - 2].End > sub[subtitles.Count - 1].Start) - { - subtitles[subtitles.Count - 2].EndTime = subtitles[subtitles.Count - 1].StartTime - 1; - } - } - - clusterStream = new MemoryStream(); - } - } - else if (subtitles.Count > 0) - { - var lastSub = subtitles[subtitles.Count - 1]; - if (lastSub.StartTime == lastSub.EndTime) - { - lastSub.EndTime = (long)((p.Start - 1) * 90.0); - if (lastSub.EndTime - lastSub.StartTime > 1000000) - { - lastSub.EndTime = lastSub.StartTime; - } - } - } - } + var subtitles = BluRaySupParser.ParseBluRaySupFromMatroska(matroskaSubtitleInfo, matroska); _subtitle = new Subtitle(); _extra = new List(); @@ -1097,25 +1048,6 @@ namespace Nikse.SubtitleEdit.Forms.BinaryEdit return true; } - private static bool ContainsBluRayStartSegment(byte[] buffer) - { - const int epochStart = 0x80; - var position = 0; - while (position + 3 <= buffer.Length) - { - var segmentType = buffer[position]; - if (segmentType == epochStart) - { - return true; - } - - var length = BluRaySupParser.BigEndianInt16(buffer, position + 1) + 3; - position += length; - } - - return false; - } - private bool LoadDvbFromMatroska(MatroskaTrackInfo matroskaSubtitleInfo, MatroskaFile matroska) { CleanUp();