public void OpenSubIdx(string vobSubFileName, string idxFileName) { VobSubPacks = new List<VobSubPack>(); if (!string.IsNullOrEmpty(idxFileName) && File.Exists(idxFileName)) { var idx = new Idx(idxFileName); IdxPalette = idx.Palette; IdxLanguages = idx.Languages; if (idx.IdxParagraphs.Count > 0) { var buffer = new byte[0x800]; // 2048 using (var fs = new FileStream(vobSubFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { foreach (var p in idx.IdxParagraphs) { if (p.FilePosition + 100 < fs.Length) { long position = p.FilePosition; fs.Seek(position, SeekOrigin.Begin); fs.Read(buffer, 0, 0x0800); if (IsSubtitlePack(buffer) || IsPrivateStream1(buffer, 0)) { var vsp = new VobSubPack(buffer, p); VobSubPacks.Add(vsp); if (IsPrivateStream1(buffer, 0)) position += vsp.PacketizedElementaryStream.Length + 6; else position += 0x800; int currentSubPictureStreamId = vsp.PacketizedElementaryStream.SubPictureStreamId.Value; while (vsp.PacketizedElementaryStream != null && vsp.PacketizedElementaryStream.SubPictureStreamId.HasValue && (vsp.PacketizedElementaryStream.Length == PacketizedElementaryStreamMaximumLength || currentSubPictureStreamId != vsp.PacketizedElementaryStream.SubPictureStreamId.Value) && position < fs.Length) { fs.Seek(position, SeekOrigin.Begin); fs.Read(buffer, 0, 0x800); vsp = new VobSubPack(buffer, p); // idx position? if (vsp.PacketizedElementaryStream != null && vsp.PacketizedElementaryStream.SubPictureStreamId.HasValue && currentSubPictureStreamId == vsp.PacketizedElementaryStream.SubPictureStreamId.Value) { VobSubPacks.Add(vsp); if (IsPrivateStream1(buffer, 0)) position += vsp.PacketizedElementaryStream.Length + 6; else position += 0x800; } else { position += 0x800; fs.Seek(position, SeekOrigin.Begin); } } } } } } return; } } // No valid idx file found - just open like vob file Open(vobSubFileName); }
/// <summary> /// Write the 5 PTS bytes to buffer /// </summary> private static void UpdatePresentationTimestamp(byte[] buffer, long addPresentationTimestamp, VobSubPack vsp) { const int presentationTimestampIndex = 23; long newPts = addPresentationTimestamp + ((long)vsp.PacketizedElementaryStream.PresentationTimestamp.Value); var buffer5B = BitConverter.GetBytes((UInt64)newPts); if (BitConverter.IsLittleEndian) { buffer[presentationTimestampIndex + 4] = (byte)(buffer5B[0] << 1 | Helper.B00000001); // last 7 bits + '1' buffer[presentationTimestampIndex + 3] = (byte)((buffer5B[0] >> 7) + (buffer5B[1] << 1)); // the next 8 bits (1 from last byte, 7 from next) buffer[presentationTimestampIndex + 2] = (byte)((buffer5B[1] >> 6 | Helper.B00000001) + (buffer5B[2] << 2)); // the next 7 bits (1 from 2nd last byte, 6 from 3rd last byte) buffer[presentationTimestampIndex + 1] = (byte)((buffer5B[2] >> 6) + (buffer5B[3] << 2)); // the next 8 bits (2 from 3rd last byte, 6 from 2rd last byte) buffer[presentationTimestampIndex] = (byte)((buffer5B[3] >> 6 | Helper.B00000001) + (buffer5B[4] << 2)); } else { buffer[presentationTimestampIndex + 4] = (byte)(buffer5B[7] << 1 | Helper.B00000001); // last 7 bits + '1' buffer[presentationTimestampIndex + 3] = (byte)((buffer5B[7] >> 7) + (buffer5B[6] << 1)); // the next 8 bits (1 from last byte, 7 from next) buffer[presentationTimestampIndex + 2] = (byte)((buffer5B[6] >> 6 | Helper.B00000001) + (buffer5B[5] << 2)); // the next 7 bits (1 from 2nd last byte, 6 from 3rd last byte) buffer[presentationTimestampIndex + 1] = (byte)((buffer5B[5] >> 6) + (buffer5B[4] << 2)); // the next 8 bits (2 from 3rd last byte, 6 from 2rd last byte) buffer[presentationTimestampIndex] = (byte)((buffer5B[4] >> 6 | Helper.B00000001) + (buffer5B[3] << 2)); } if (vsp.PacketizedElementaryStream.PresentationTimestampDecodeTimestampFlags == Helper.B00000010) buffer[presentationTimestampIndex] += Helper.B00100000; else buffer[presentationTimestampIndex] += Helper.B00110000; }
public void OpenSubIdx(string vobSubFileName, string idxFileName) { VobSubPacks = new List <VobSubPack>(); if (!string.IsNullOrEmpty(idxFileName) && File.Exists(idxFileName)) { var idx = new Idx(idxFileName); IdxPalette = idx.Palette; IdxLanguages = idx.Languages; if (idx.IdxParagraphs.Count > 0) { var buffer = new byte[0x800]; // 2048 using (var fs = new FileStream(vobSubFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { foreach (var p in idx.IdxParagraphs) { if (p.FilePosition + 100 < fs.Length) { long position = p.FilePosition; fs.Seek(position, SeekOrigin.Begin); fs.Read(buffer, 0, 0x0800); if (IsSubtitlePack(buffer) || IsPrivateStream1(buffer, 0)) { var vsp = new VobSubPack(buffer, p); VobSubPacks.Add(vsp); if (IsPrivateStream1(buffer, 0)) { position += vsp.PacketizedElementaryStream.Length + 6; } else { position += 0x800; } int currentSubPictureStreamId = 0; if (vsp.PacketizedElementaryStream.SubPictureStreamId != null) { currentSubPictureStreamId = vsp.PacketizedElementaryStream.SubPictureStreamId.Value; } while (vsp.PacketizedElementaryStream != null && vsp.PacketizedElementaryStream.SubPictureStreamId.HasValue && (vsp.PacketizedElementaryStream.Length == PacketizedElementaryStreamMaximumLength || currentSubPictureStreamId != vsp.PacketizedElementaryStream.SubPictureStreamId.Value) && position < fs.Length) { fs.Seek(position, SeekOrigin.Begin); fs.Read(buffer, 0, 0x800); vsp = new VobSubPack(buffer, p); // idx position? if (vsp.PacketizedElementaryStream != null && vsp.PacketizedElementaryStream.SubPictureStreamId.HasValue && currentSubPictureStreamId == vsp.PacketizedElementaryStream.SubPictureStreamId.Value) { VobSubPacks.Add(vsp); if (IsPrivateStream1(buffer, 0)) { position += vsp.PacketizedElementaryStream.Length + 6; } else { position += 0x800; } } else { position += 0x800; fs.Seek(position, SeekOrigin.Begin); } } } } } } return; } } // No valid idx file found - just open like vob file Open(vobSubFileName); }
private void RipSubtitles(string vobFileName, MemoryStream stream, int vobNumber) { long firstNavStartPts = 0; using (var fs = RetryOpenRead(vobFileName)) { var buffer = new byte[0x800]; long position = 0; progressBarRip.Maximum = 100; progressBarRip.Value = 0; int lba = 0; long length = fs.Length; while (position < length && !_abort) { int bytesRead = 0; // Reading and test for IO errors... and allow abort/retry/ignore var tryAgain = true; while (tryAgain && position < length) { tryAgain = false; try { fs.Seek(position, SeekOrigin.Begin); bytesRead = fs.Read(buffer, 0, 0x800); } catch (IOException exception) { var result = MessageBox.Show(string.Format("An error occured while reading file: {0}", exception.Message), "", MessageBoxButtons.AbortRetryIgnore); if (result == DialogResult.Abort) return; if (result == DialogResult.Retry) tryAgain = true; if (result == DialogResult.Ignore) { position += 0x800; tryAgain = true; } } } if (VobSubParser.IsMpeg2PackHeader(buffer)) { var vsp = new VobSubPack(buffer, null); if (IsSubtitlePack(buffer)) { if (vsp.PacketizedElementaryStream.PresentationTimestamp.HasValue && _accumulatedPresentationTimestamp != 0) UpdatePresentationTimestamp(buffer, _accumulatedPresentationTimestamp, vsp); stream.Write(buffer, 0, 0x800); if (bytesRead < 0x800) stream.Write(Encoding.ASCII.GetBytes(new string(' ', 0x800 - bytesRead)), 0, 0x800 - bytesRead); } else if (IsPrivateStream2(buffer, 0x26)) { if (Helper.GetEndian(buffer, 0x0026, 4) == 0x1bf && Helper.GetEndian(buffer, 0x0400, 4) == 0x1bf) { uint vobuSPtm = Helper.GetEndian(buffer, 0x0039, 4); uint vobuEPtm = Helper.GetEndian(buffer, 0x003d, 4); _lastPresentationTimestamp = vobuEPtm; if (firstNavStartPts == 0) { firstNavStartPts = vobuSPtm; if (vobNumber == 0) _accumulatedPresentationTimestamp = -vobuSPtm; } if (vobuSPtm + firstNavStartPts + _accumulatedPresentationTimestamp < _lastVobPresentationTimestamp) { _accumulatedPresentationTimestamp += _lastNavEndPts - vobuSPtm; } else if (_lastNavEndPts > vobuEPtm) { _accumulatedPresentationTimestamp += _lastNavEndPts - vobuSPtm; } _lastNavEndPts = vobuEPtm; } } } position += 0x800; var progress = (int)((position * 100) / length); if (progress != progressBarRip.Value) { progressBarRip.Value = progress; TaskbarList.SetProgressValue(_taskbarFormHandle, (vobNumber * 100) + progressBarRip.Value, progressBarRip.Maximum * listBoxVobFiles.Items.Count); Application.DoEvents(); } lba++; } } _lastVobPresentationTimestamp = _lastPresentationTimestamp; }