From f0cd90cd63d52606ee4a6bdea1dffab1d61524db Mon Sep 17 00:00:00 2001 From: Nikolaj Olsson Date: Thu, 31 Oct 2019 19:53:32 +0100 Subject: [PATCH] Work on teletext --- libse/TransportStream/DvbSubPes.cs | 69 +++++++++---------- libse/TransportStream/Teletext.cs | 37 +++++++--- libse/TransportStream/TeletextRunSettings.cs | 1 + .../TransportStream/TransportStreamParser.cs | 13 ++-- src/Forms/TransportStreamSubtitleChooser.cs | 4 +- 5 files changed, 70 insertions(+), 54 deletions(-) diff --git a/libse/TransportStream/DvbSubPes.cs b/libse/TransportStream/DvbSubPes.cs index 3d3a74422..efe4f15ac 100644 --- a/libse/TransportStream/DvbSubPes.cs +++ b/libse/TransportStream/DvbSubPes.cs @@ -115,11 +115,11 @@ namespace Nikse.SubtitleEdit.Core.TransportStream Buffer.BlockCopy(buffer, dataIndex - 1, _dataBuffer, 0, _dataBuffer.Length); // why subtract one from dataIndex??? } - public Dictionary GetTeletext(int packetId, TeletextRunSettings teletextRunSettings) + public Dictionary GetTeletext(int packetId, TeletextRunSettings teletextRunSettings) { if (!IsTeletext) { - return new Dictionary(); + return new Dictionary(); } var pts = PresentationTimestamp.HasValue ? (long)PresentationTimestamp.Value / 90 : 0; @@ -167,7 +167,7 @@ namespace Nikse.SubtitleEdit.Core.TransportStream pages.Add(888); // default } - var teletextPages = new Dictionary(); + var teletextPages = new Dictionary(); Teletext.Fout.Clear(); Teletext._lastTimestamp = 0; Teletext._globalTimestamp = 0; @@ -180,53 +180,52 @@ namespace Nikse.SubtitleEdit.Core.TransportStream // pages = new List { pageNumBcd }; var page = pageNum; int teletextPackageNo = 0; - //foreach (var page in pages) + Teletext.Fout.Clear(); + Teletext.config.Page = page; // ((page / 100) << 8) | ((page / 10 % 10) << 4) | (page % 10); ; + Teletext.config.Tid = packetId; + i = 1; + while (i <= _dataBuffer.Length - 6) { - Teletext.Fout.Clear(); - Teletext.config.Page = page; // ((page / 100) << 8) | ((page / 10 % 10) << 4) | (page % 10); ; - Teletext.config.Tid = packetId; - i = 1; - while (i <= _dataBuffer.Length - 6) - { - teletextPackageNo++; - sb.AppendLine("----------------"); - sb.AppendLine($"{teletextPackageNo} for packet-id {packetId}"); + teletextPackageNo++; + sb.AppendLine("----------------"); + sb.AppendLine($"{teletextPackageNo} for packet-id {packetId}"); - var dataUnitId = _dataBuffer[i++]; - var dataUnitLen = _dataBuffer[i++]; - sb.AppendLine($"dataUnitId: {dataUnitId}"); - sb.AppendLine($"dataUnitLen: {dataUnitLen}"); - if (dataUnitId == (int)Teletext.DataUnitT.DataUnitEbuTeletextNonSubtitle || dataUnitId == (int)Teletext.DataUnitT.DataUnitEbuTeletextSubtitle) + var dataUnitId = _dataBuffer[i++]; + var dataUnitLen = _dataBuffer[i++]; + sb.AppendLine($"dataUnitId: {dataUnitId}"); + sb.AppendLine($"dataUnitLen: {dataUnitLen}"); + if (dataUnitId == (int)Teletext.DataUnitT.DataUnitEbuTeletextNonSubtitle || dataUnitId == (int)Teletext.DataUnitT.DataUnitEbuTeletextSubtitle) + { + // teletext payload has always size 44 bytes + if (dataUnitLen == 44) { - // teletext payload has always size 44 bytes - if (dataUnitLen == 44) + + // reverse endianness (via lookup table), ETS 300 706, chapter 7.1 + for (var j = 0; j < dataUnitLen; j++) { - - // reverse endianness (via lookup table), ETS 300 706, chapter 7.1 - for (var j = 0; j < dataUnitLen; j++) - { - _dataBuffer[i + j] = TeletextHamming.Reverse8[_dataBuffer[i + j]]; - } - - Teletext.ProcessTelxPacket((Teletext.DataUnitT)dataUnitId, new Teletext.TeletextPacketPayload(_dataBuffer, i), lastTimestamp, teletextRunSettings, sb); //TODO: optimize use databuffer + _dataBuffer[i + j] = TeletextHamming.Reverse8[_dataBuffer[i + j]]; } + + Teletext.ProcessTelxPacket((Teletext.DataUnitT)dataUnitId, new Teletext.TeletextPacketPayload(_dataBuffer, i), lastTimestamp, teletextRunSettings, sb); //TODO: optimize use databuffer } - i += dataUnitLen; } - var text = Teletext.Fout.ToString().Trim(); - if (!string.IsNullOrEmpty(text)) + i += dataUnitLen; + } + foreach (var pNo in teletextRunSettings.PageNumberAndParagraph.Keys) + { + if (teletextRunSettings.PageNumberAndParagraph.ContainsKey(pNo) && teletextRunSettings.PageNumberAndParagraph[pNo] != null) { - var p = teletextRunSettings.PageNumber; - if (teletextPages.ContainsKey(p)) + if (teletextPages.ContainsKey(pNo)) { - teletextPages[p] += Environment.NewLine + Environment.NewLine + text; + teletextPages[pNo] = teletextRunSettings.PageNumberAndParagraph[pNo]; } else { - teletextPages.Add(p, text); + teletextPages.Add(pNo, teletextRunSettings.PageNumberAndParagraph[pNo]); } } } + teletextRunSettings.PageNumberAndParagraph.Clear(); return teletextPages; } diff --git a/libse/TransportStream/Teletext.cs b/libse/TransportStream/Teletext.cs index 397dc17de..3931b501e 100644 --- a/libse/TransportStream/Teletext.cs +++ b/libse/TransportStream/Teletext.cs @@ -334,7 +334,7 @@ namespace Nikse.SubtitleEdit.Core.TransportStream } - static void ProcessPage(TeletextPage page) + static void ProcessPage(TeletextPage page, TeletextRunSettings teletextRunSettings) { //#if DEBUG // for (int row = 1; row < 25; row++) @@ -361,6 +361,8 @@ namespace Nikse.SubtitleEdit.Core.TransportStream } if (pageIsEmpty) return; + var paragraph = new Paragraph(); + if (page.ShowTimestamp > page.HideTimestamp) { page.HideTimestamp = page.ShowTimestamp; @@ -376,8 +378,14 @@ namespace Nikse.SubtitleEdit.Core.TransportStream var timeCodeShow = TimestampToSrtTime(page.ShowTimestamp); var timeCodeHide = TimestampToSrtTime(page.HideTimestamp); Fout.AppendLine($"{++_framesProduced}{Environment.NewLine}{timeCodeShow} --> {timeCodeHide}"); + + paragraph.Number = _framesProduced; + paragraph.StartTime = new TimeCode(page.ShowTimestamp); + paragraph.EndTime = new TimeCode(page.HideTimestamp); } + Fout.Clear(); //nixe - now we use paragraph + // process data for (var row = 1; row < 25; row++) { @@ -409,7 +417,7 @@ namespace Nikse.SubtitleEdit.Core.TransportStream if (colStop > 39) continue; // ETS 300 706, chapter 12.2: Alpha White ("Set-After") - Start-of-row default condition. - // used for colour changes _before_ start box mark + // used for color changes _before_ start box mark // white is default as stated in ETS 300 706, chapter 12.2 // black(0), red(1), green(2), yellow(3), blue(4), magenta(5), cyan(6), white(7) var foregroundColor = 0x7; @@ -492,6 +500,15 @@ namespace Nikse.SubtitleEdit.Core.TransportStream Fout.Append(config.SeMode ? " " : Environment.NewLine); } Fout.AppendLine(); + paragraph.Text = Fout.ToString().TrimEnd(); + if (!teletextRunSettings.PageNumberAndParagraph.ContainsKey(teletextRunSettings.PageNumber)) + { + teletextRunSettings.PageNumberAndParagraph.Add(teletextRunSettings.PageNumber, paragraph); + } + else + { + throw new NotImplementedException(); + } } public static int GetPageNumber(TeletextPacketPayload packet) @@ -576,11 +593,11 @@ namespace Nikse.SubtitleEdit.Core.TransportStream CcMap[i] |= (byte)(flagSubtitle << (m - 1)); - if (config.Page == 0 && flagSubtitle == (int)BoolT.Yes && i < 0xff) - { - config.Page = (m << 8) | (TeletextHamming.UnHamming84(packet.Data[1]) << 4) | TeletextHamming.UnHamming84(packet.Data[0]); - Console.WriteLine($"- No teletext page specified, first received suitable page is {config.Page}, not guaranteed"); - } + //if (config.Page == 0 && flagSubtitle == (int)BoolT.Yes && i < 0xff) + //{ + // config.Page = (m << 8) | (TeletextHamming.UnHamming84(packet.Data[1]) << 4) | TeletextHamming.UnHamming84(packet.Data[0]); + // Console.WriteLine($"- No teletext page specified, first received suitable page is {config.Page}, not guaranteed"); + //} // Page number and control bits var pageNumber = (m << 8) | (TeletextHamming.UnHamming84(packet.Data[1]) << 4) | TeletextHamming.UnHamming84(packet.Data[0]); @@ -605,8 +622,8 @@ namespace Nikse.SubtitleEdit.Core.TransportStream if (_transmissionMode == TransmissionMode.TransmissionModeParallel && dataUnitId != DataUnitT.DataUnitEbuTeletextSubtitle) return; if (_receivingData && ( - _transmissionMode == TransmissionMode.TransmissionModeSerial && Page(pageNumber) != Page(config.Page) || - _transmissionMode == TransmissionMode.TransmissionModeParallel && Page(pageNumber) != Page(config.Page) && m == Magazine(config.Page) + _transmissionMode == TransmissionMode.TransmissionModeSerial && Page(pageNumber) != Page(teletextRunSettings.PageNumberBcd) || + _transmissionMode == TransmissionMode.TransmissionModeParallel && Page(pageNumber) != Page(teletextRunSettings.PageNumberBcd) && m == Magazine(teletextRunSettings.PageNumberBcd) )) { _receivingData = false; @@ -624,7 +641,7 @@ namespace Nikse.SubtitleEdit.Core.TransportStream { // it would be nice, if subtitle hides on previous video frame, so we contract 40 ms (1 frame @25 fps) PageBuffer.HideTimestamp = timestamp - 40; - ProcessPage(PageBuffer); + ProcessPage(PageBuffer, teletextRunSettings); } PageBuffer.ShowTimestamp = timestamp; diff --git a/libse/TransportStream/TeletextRunSettings.cs b/libse/TransportStream/TeletextRunSettings.cs index 9b8deb940..c5deeeda8 100644 --- a/libse/TransportStream/TeletextRunSettings.cs +++ b/libse/TransportStream/TeletextRunSettings.cs @@ -11,5 +11,6 @@ namespace Nikse.SubtitleEdit.Core.TransportStream public int TransmissionMode { get; set; } public HashSet PageNumbersInt { get; set; } = new HashSet(); public HashSet PageNumbersBcd { get; set; } = new HashSet(); + public Dictionary PageNumberAndParagraph { get; set; } = new Dictionary(); } } diff --git a/libse/TransportStream/TransportStreamParser.cs b/libse/TransportStream/TransportStreamParser.cs index 2379ca128..c5b23cf24 100644 --- a/libse/TransportStream/TransportStreamParser.cs +++ b/libse/TransportStream/TransportStreamParser.cs @@ -23,7 +23,7 @@ namespace Nikse.SubtitleEdit.Core.TransportStream public List SubtitlePackets { get; private set; } private Dictionary> SubtitlesLookup { get; set; } private Dictionary> DvbSubtitlesLookup { get; set; } - public Dictionary> TeletextSubtitlesLookup { get; set; } + public Dictionary>> TeletextSubtitlesLookup { get; set; } public bool IsM2TransportStream { get; private set; } public ulong FirstVideoPts { get; private set; } @@ -57,7 +57,7 @@ namespace Nikse.SubtitleEdit.Core.TransportStream var m2TsTimeCodeBuffer = new byte[4]; long position = 0; SubtitlesLookup = new Dictionary>(); - TeletextSubtitlesLookup = new Dictionary>(); + TeletextSubtitlesLookup = new Dictionary>>(); TeletextRunSettings teletextRunSettings = new TeletextRunSettings(); // check for Topfield .rec file @@ -139,24 +139,23 @@ namespace Nikse.SubtitleEdit.Core.TransportStream var textDictionary = item.GetTeletext(packet.PacketId, teletextRunSettings); foreach (var dic in textDictionary) { - if (dic.Value.Length > 0) + if (!string.IsNullOrEmpty(dic.Value.Text)) { - var text = dic.Value + Environment.NewLine + Environment.NewLine; if (TeletextSubtitlesLookup.ContainsKey(packet.PacketId)) { var innerDic = TeletextSubtitlesLookup[packet.PacketId]; if (innerDic.ContainsKey(dic.Key)) { - innerDic[dic.Key].Append(text); + innerDic[dic.Key].Add(dic.Value); } else { - innerDic.Add(dic.Key, new StringBuilder(text)); + innerDic.Add(dic.Key, new List { dic.Value }); } } else { - TeletextSubtitlesLookup.Add(packet.PacketId, new Dictionary { { dic.Key, new StringBuilder(text) } }); + TeletextSubtitlesLookup.Add(packet.PacketId, new Dictionary> { { dic.Key, new List { dic.Value } } }); } } } diff --git a/src/Forms/TransportStreamSubtitleChooser.cs b/src/Forms/TransportStreamSubtitleChooser.cs index aef578f95..d7a82ba0f 100644 --- a/src/Forms/TransportStreamSubtitleChooser.cs +++ b/src/Forms/TransportStreamSubtitleChooser.cs @@ -110,7 +110,7 @@ namespace Nikse.SubtitleEdit.Forms Text = "Teletext program " + program.Key + " page " + kvp.Key + " in " + language, IsTeletext = true, Pid = program.Key, - Srt = kvp.Value.ToString() + Srt = new SubRip().ToText(new Subtitle(kvp.Value), null) }); } else @@ -120,7 +120,7 @@ namespace Nikse.SubtitleEdit.Forms Text = "Teletext program " + program.Key + " page " + kvp.Key, IsTeletext = true, Pid = program.Key, - Srt = kvp.Value.ToString() + Srt = new SubRip().ToText(new Subtitle(kvp.Value), null) }); } }