public VobSubPack Constructor(byte[] buffer, IdxParagraph idxLine)
        {
            VobSubPack target = new VobSubPack(buffer, idxLine);
            return target;

            // TODO: add assertions to method VobSubPackTest.Constructor(Byte[], IdxParagraph)
        }
예제 #2
0
        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);
        }
예제 #3
0
        /// <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;
        }
예제 #4
0
        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;
        }