public VobSubPack Constructor(byte[] buffer, IdxParagraph idxLine) { VobSubPack target = new VobSubPack(buffer, idxLine); return target; // TODO: add assertions to method VobSubPackTest.Constructor(Byte[], IdxParagraph) }
internal 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; }
private void RipSubtitles(string vobFileName, MemoryStream stream, int vobNumber) { long firstNavStartPTS = 0; FileStream fs = null; bool tryAgain = true; while (tryAgain) { try { fs = new FileStream(vobFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); tryAgain = false; } catch (IOException exception) { var result = MessageBox.Show(string.Format("An error occured while opening file: {0}", exception.Message), "", MessageBoxButtons.RetryCancel); if (result == DialogResult.Cancel) return; if (result == DialogResult.Retry) tryAgain = true; } } byte[] 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 tryAgain = true; while (tryAgain && position < length) { tryAgain = false; try { fs.Seek(position, SeekOrigin.Begin); bytesRead = fs.Read(buffer, 0, 0x0800); } 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)) { VobSubPack 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, 0x400, 4) == 0x1bf) { uint vobu_s_ptm = Helper.GetEndian(buffer, 0x0039, 4); uint vobu_e_ptm = Helper.GetEndian(buffer, 0x003d, 4); _lastPresentationTimeStamp = vobu_e_ptm; if (firstNavStartPTS == 0) { firstNavStartPTS = vobu_s_ptm; if (vobNumber == 0) _accumulatedPresentationTimeStamp = -vobu_s_ptm; } if (vobu_s_ptm + firstNavStartPTS + _accumulatedPresentationTimeStamp < _lastVobPresentationTimeStamp) { _accumulatedPresentationTimeStamp += _lastNavEndPts - vobu_s_ptm; } else if (_lastNavEndPts > vobu_e_ptm) { _accumulatedPresentationTimeStamp += _lastNavEndPts - vobu_s_ptm; } _lastNavEndPts = vobu_e_ptm; } } } position += 0x800; progressBarRip.Value = (int)((position * 100) / length); Application.DoEvents(); lba++; } fs.Close(); _lastVobPresentationTimeStamp = _lastPresentationTimeStamp; }
internal 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> /// The rip subtitles. /// </summary> /// <param name="vobFileName"> /// The vob file name. /// </param> /// <param name="stream"> /// The stream. /// </param> /// <param name="vobNumber"> /// The vob number. /// </param> private void RipSubtitles(string vobFileName, MemoryStream stream, int vobNumber) { long firstNavStartPts = 0; using (var fs = FileUtil.RetryOpenRead(vobFileName)) { var buffer = new byte[0x800]; long position = 0; this.progressBarRip.Maximum = 100; this.progressBarRip.Value = 0; int lba = 0; long length = fs.Length; while (position < length && !this._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), string.Empty, 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 && this._accumulatedPresentationTimestamp != 0) { UpdatePresentationTimestamp(buffer, this._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); this._lastPresentationTimestamp = vobuEPtm; if (firstNavStartPts == 0) { firstNavStartPts = vobuSPtm; if (vobNumber == 0) { this._accumulatedPresentationTimestamp = -vobuSPtm; } } if (vobuSPtm + firstNavStartPts + this._accumulatedPresentationTimestamp < this._lastVobPresentationTimestamp) { this._accumulatedPresentationTimestamp += this._lastNavEndPts - vobuSPtm; } else if (this._lastNavEndPts > vobuEPtm) { this._accumulatedPresentationTimestamp += this._lastNavEndPts - vobuSPtm; } this._lastNavEndPts = vobuEPtm; } } } position += 0x800; var progress = (int)((position * 100) / length); if (progress != this.progressBarRip.Value) { this.progressBarRip.Value = progress; TaskbarList.SetProgressValue(this._taskbarFormHandle, (vobNumber * 100) + this.progressBarRip.Value, this.progressBarRip.Maximum * this.listBoxVobFiles.Items.Count); Application.DoEvents(); } lba++; } } this._lastVobPresentationTimestamp = this._lastPresentationTimestamp; }