Ejemplo n.º 1
0
        private void input_FileSelected(FileBar sender, FileBarEventArgs args)
        {
            audioDelay.Value = PrettyFormatting.getDelayAndCheck(input.Filename) ?? 0;

            string strLanguage = LanguageSelectionContainer.GetLanguageFromFileName(System.IO.Path.GetFileNameWithoutExtension(input.Filename));

            if (!String.IsNullOrEmpty(strLanguage))
            {
                SetLanguage(strLanguage);
            }
            else if (input.Filename.ToLowerInvariant().EndsWith(".idx"))
            {
                List <SubtitleInfo> subTracks;
                idxReader.readFileProperties(input.Filename, out subTracks);
                if (subTracks.Count > 0)
                {
                    SetLanguage(LanguageSelectionContainer.LookupISOCode(subTracks[0].Name));
                }
            }

            raiseEvent();
        }
Ejemplo n.º 2
0
        /// <summary>
        /// fills the <see cref="TitleInfo"/> with informations
        /// </summary>
        private void GetTitleInfo(int titleSetNumber, ref TitleInfo item)
        {
            item.VideoStream     = new VideoProperties();
            item.AudioStreams    = new List <AudioProperties>();
            item.SubtitleStreams = new List <SubpictureProperties>();
            item.Chapters        = new List <TimeSpan>();

            var buffer = new byte[192];

            using (var fs = File.OpenRead(Path.Combine(_path, $"VTS_{titleSetNumber:00}_0.IFO")))
            {
                fs.Seek(0x00C8, SeekOrigin.Begin);
                fs.Read(buffer, 0, 4);
                fs.Seek(0x0200, SeekOrigin.Begin);
                fs.Read(buffer, 0, 2);

                item.VideoStream.DisplayFormat = (DvdVideoPermittedDisplayFormat)GetBits(buffer, 2, 0);
                item.VideoStream.AspectRatio   = (DvdVideoAspectRatio)GetBits(buffer, 2, 2);
                item.VideoStream.VideoStandard = (DvdVideoStandard)GetBits(buffer, 2, 4);

                switch (item.VideoStream.VideoStandard)
                {
                case DvdVideoStandard.NTSC:
                    item.VideoStream.Framerate            = 30000f / 1001f;
                    item.VideoStream.FrameRateNumerator   = 30000;
                    item.VideoStream.FrameRateDenominator = 1001;
                    break;

                case DvdVideoStandard.PAL:
                    item.VideoStream.Framerate            = 25f;
                    item.VideoStream.FrameRateNumerator   = 25;
                    item.VideoStream.FrameRateDenominator = 1;
                    break;
                }
                item.VideoStream.CodingMode      = (DvdVideoMpegVersion)GetBits(buffer, 2, 6);
                item.VideoStream.VideoResolution = (DvdVideoResolution)GetBits(buffer, 3, 11) +
                                                   ((int)item.VideoStream.VideoStandard * 8);

                fs.Read(buffer, 0, 2);
                var numAudio = GetBits(buffer, 16, 0);
                for (var audioNum = 0; audioNum < numAudio; audioNum++)
                {
                    fs.Read(buffer, 0, 8);
                    var langMode    = GetBits(buffer, 2, 2);
                    var codingMode  = GetBits(buffer, 3, 5);
                    var audioStream = new AudioProperties
                    {
                        CodingMode   = (DvdAudioFormat)codingMode,
                        Channels     = GetBits(buffer, 3, 8) + 1,
                        SampleRate   = 48000,
                        Quantization = (DvdAudioQuantization)GetBits(buffer, 2, 14),
                        StreamId     = DvdAudioId.ID[codingMode] + audioNum,
                        StreamIndex  = audioNum + 1
                    };

                    if (langMode == 1)
                    {
                        var langChar1 = (char)GetBits(buffer, 8, 16);
                        var langChar2 = (char)GetBits(buffer, 8, 24);

                        audioStream.Language = LanguageSelectionContainer.LookupISOCode($"{langChar1}{langChar2}");
                    }
                    else
                    {
                        audioStream.Language = LanguageSelectionContainer.LookupISOCode("  ");
                    }
                    audioStream.Extension = (DvdAudioType)GetBits(buffer, 8, 40);
                    item.AudioStreams.Add(audioStream);
                }

                fs.Seek(0x0254, SeekOrigin.Begin);
                fs.Read(buffer, 0, 2);
                var numSubs = GetBits(buffer, 16, 0);
                for (var subNum = 0; subNum < numSubs; subNum++)
                {
                    fs.Read(buffer, 0, 6);
                    var langMode = GetBits(buffer, 2, 0);
                    var sub      = new SubpictureProperties
                    {
                        Format      = (DvdSubpictureFormat)GetBits(buffer, 3, 5),
                        StreamId    = 0x20 + subNum,
                        StreamIndex = subNum + 1
                    };

                    if (langMode == 1)
                    {
                        var langChar1 = (char)GetBits(buffer, 8, 16);
                        var langChar2 = (char)GetBits(buffer, 8, 24);

                        var langCode = langChar1.ToString(CultureInfo.InvariantCulture) +
                                       langChar2.ToString(CultureInfo.InvariantCulture);

                        sub.Language = LanguageSelectionContainer.LookupISOCode(langCode);
                    }
                    else
                    {
                        sub.Language = LanguageSelectionContainer.LookupISOCode("  ");
                    }
                    sub.Extension = (DvdSubpictureType)GetBits(buffer, 8, 40);
                    item.SubtitleStreams.Add(sub);
                }

                fs.Seek(0xCC, SeekOrigin.Begin);
                fs.Read(buffer, 0, 4);
                var pgciSector = GetBits(buffer, 32, 0);
                var pgciAdress = pgciSector * SectorLength;

                fs.Seek(pgciAdress, SeekOrigin.Begin);
                fs.Read(buffer, 0, 8);

                fs.Seek(8 * (item.TitleNumberInSet - 1), SeekOrigin.Current);
                fs.Read(buffer, 0, 8);
                var offsetPgc = GetBits(buffer, 32, 32);
                fs.Seek(pgciAdress + offsetPgc + 2, SeekOrigin.Begin);

                fs.Read(buffer, 0, 6);
                var numCells = GetBits(buffer, 8, 8);

                var hour   = GetBits(buffer, 8, 16);
                var minute = GetBits(buffer, 8, 24);
                var second = GetBits(buffer, 8, 32);
                var msec   = GetBits(buffer, 8, 40);

                item.VideoStream.Runtime = DvdTime2TimeSpan(hour, minute, second, msec);

                fs.Seek(224, SeekOrigin.Current);
                fs.Read(buffer, 0, 2);
                var cellmapOffset = GetBits(buffer, 16, 0);

                fs.Seek(pgciAdress + cellmapOffset + offsetPgc, SeekOrigin.Begin);

                var chapter = new TimeSpan();
                item.Chapters.Add(chapter);

                for (var i = 0; i < numCells; i++)
                {
                    fs.Read(buffer, 0, 24);
                    var chapHour   = GetBits(buffer, 8, 4 * 8);
                    var chapMinute = GetBits(buffer, 8, 5 * 8);
                    var chapSecond = GetBits(buffer, 8, 6 * 8);
                    var chapMsec   = GetBits(buffer, 8, 7 * 8);
                    chapter = chapter.Add(DvdTime2TimeSpan(chapHour, chapMinute, chapSecond, chapMsec));

                    item.Chapters.Add(chapter);
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// get several Subtitles Informations from the IFO file
        /// </summary>
        /// <param name="fileName">name of the IFO file</param>
        /// <returns>several infos as String</returns>
        public static string[] GetSubtitlesStreamsInfos(string FileName, int iPGC, bool bGetAllStreams)
        {
            byte[]   buff       = new byte[4];
            string[] substreams = new string[32]; // according to the specs 32 is the max value for subtitles streams

            try
            {
                // get the number of subpicture streams in VTS_VOBS
                int iSubtitleCount = ToInt16(GetFileBlock(FileName, 0x254, 2));
                if (iSubtitleCount == 0 && !bGetAllStreams)
                {
                    return(new string[0]);
                }

                string[] subdesc = new string[32];

                FileStream   fs = new FileStream(FileName, FileMode.Open, FileAccess.Read);
                BinaryReader br = new BinaryReader(fs);
                Stream       sr = br.BaseStream;

                // go to the subpicture attributes of VTS_VOBS
                sr.Seek(0x256, SeekOrigin.Begin);
                for (int i = 0; i < 32; i++)
                {
                    // Presence (1 bit), Coding Mode (1bit), Short Language Code (2bits), Language Extension (1bit), Sub Picture Caption Type (1bit)

                    // ignore presence & coding mode and go to short language code
                    sr.Seek(0x2, SeekOrigin.Current);

                    // read short language code
                    br.Read(buff, 0, 2);

                    string ShortLangCode = String.Format("{0}{1}", (char)buff[0], (char)buff[1]);
                    subdesc[i] = LanguageSelectionContainer.LookupISOCode(ShortLangCode) + " - ";
                    if (String.IsNullOrEmpty(subdesc[i]))
                    {
                        subdesc[i] = "unknown - ";
                    }

                    // Go to Code Extension
                    sr.Seek(1, SeekOrigin.Current);
                    buff[0] = br.ReadByte();

                    switch (buff[0] & 0x0F)
                    {
                    // from http://dvd.sourceforge.net/dvdinfo/sprm.html
                    case 1: subdesc[i] += "Caption "; break;

                    case 2: subdesc[i] += "Caption (Large) "; break;

                    case 3: subdesc[i] += "Caption for Children "; break;

                    case 5: subdesc[i] += "Closed Caption "; break;

                    case 6: subdesc[i] += "Closed Caption (Large) "; break;

                    case 7: subdesc[i] += "Closed Caption for Children "; break;

                    case 9: subdesc[i] += "Forced Caption "; break;

                    case 13: subdesc[i] += "Director Comments "; break;

                    case 14: subdesc[i] += "Director Comments (Large) "; break;

                    case 15: subdesc[i] += "Director Comments for Children "; break;
                    }
                }

                // get VTS_PGCI
                long VTS_PGCI = GetPCGIP_Position(FileName);

                // find the VTS_PGC starting address of the requested PGC number in VTS_PGCI
                long VTS_PGC = VTS_PGCI + GetPGCOffset(FileName, VTS_PGCI, iPGC);

                // go to the Subpicture Stream Control (PGC_SPST_CTL) in VTS_PGC of the requested PGC number
                sr.Seek(VTS_PGC + 0x1C, SeekOrigin.Begin);

                byte[] iCountType = new byte[4];
                for (int i = 0; i < 32; i++)
                {
                    // read subtitle info of stream i
                    br.Read(buff, 0, 4);

                    // if bit 7 = 1 (true) the stream is available
                    if (!GetBit(buff[0], 7))
                    {
                        continue;
                    }

                    // remove bits 7, 6 and 5 as they are reserved
                    for (int j = 0; j < 4; j++)
                    {
                        if (GetBit(buff[j], 7))
                        {
                            buff[j] -= 128;
                        }
                        if (GetBit(buff[j], 6))
                        {
                            buff[j] -= 64;
                        }
                        if (GetBit(buff[j], 5))
                        {
                            buff[j] -= 32;
                        }
                    }

                    if (buff[0] > 0)
                    {
                        substreams[buff[0]] = "[" + String.Format("{0:00}", buff[0]) + "] - " + subdesc[i];
                        iCountType[0]++;
                    }
                    if (buff[1] > 0)
                    {
                        substreams[buff[1]] = "[" + String.Format("{0:00}", buff[1]) + "] - " + subdesc[i];
                        iCountType[1]++;
                    }
                    if (buff[2] > 0)
                    {
                        substreams[buff[2]] = "[" + String.Format("{0:00}", buff[2]) + "] - " + subdesc[i];
                        iCountType[2]++;
                    }
                    if (buff[3] > 0)
                    {
                        substreams[buff[3]] = "[" + String.Format("{0:00}", buff[3]) + "] - " + subdesc[i];
                        iCountType[3]++;
                    }

                    // as stream ID 0 is impossible to detect, we have to guess here
                    if (String.IsNullOrEmpty(substreams[0]))
                    {
                        if (buff[0] == 0 || buff[1] == 0 || buff[2] == 0 || buff[3] == 0)
                        {
                            substreams[0] = "[" + String.Format("{0:00}", 0) + "] - " + subdesc[i];
                        }
                    }
                }

                // check how many different types are there & if therefore the type description has to be added
                int iDifferentTypes = 0;
                if (iCountType[0] > 0)
                {
                    iDifferentTypes++;
                }
                if (iCountType[1] > 0)
                {
                    iDifferentTypes++;
                }
                if (iCountType[2] > 0)
                {
                    iDifferentTypes++;
                }
                if (iCountType[3] > 0)
                {
                    iDifferentTypes++;
                }
                bool bAddTypes = iDifferentTypes > 1;
                if (bAddTypes)
                {
                    for (int i = 0; i < subdesc.Length; i++)
                    {
                        if (!String.IsNullOrEmpty(subdesc[i]))
                        {
                            subdesc[i] += (subdesc[i].Substring(subdesc[i].Length - 1).Equals(" ") ? "(" : " (");
                        }
                    }

                    // go to the Subpicture Stream Control in VTS_PGC of the requested PGC number
                    sr.Seek(VTS_PGC + 0x1C, SeekOrigin.Begin);

                    int iCountStream = 0;
                    for (int i = 0; i < 32; i++)
                    {
                        // read subtitle info of stream i
                        br.Read(buff, 0, 4);

                        // if bit 7 = 1 (true) the stream is available
                        if (!GetBit(buff[0], 7))
                        {
                            continue;
                        }

                        iCountStream++;

                        // remove bits 7, 6 and 5 as they are reserved
                        for (int j = 0; j < 4; j++)
                        {
                            if (GetBit(buff[j], 7))
                            {
                                buff[j] -= 128;
                            }
                            if (GetBit(buff[j], 6))
                            {
                                buff[j] -= 64;
                            }
                            if (GetBit(buff[j], 5))
                            {
                                buff[j] -= 32;
                            }
                        }

                        if (buff[0] > 0)
                        {
                            if (substreams[buff[0]].Substring(substreams[buff[0]].Length - 1).Equals(")"))
                            {
                                substreams[buff[0]] = substreams[buff[0]].Substring(0, substreams[buff[0]].Length - 1) + "/4:3)";
                            }
                            else
                            {
                                substreams[buff[0]] += "(4:3)";
                            }
                        }
                        if (buff[1] > 0)
                        {
                            if (substreams[buff[1]].Substring(substreams[buff[1]].Length - 1).Equals(")"))
                            {
                                substreams[buff[1]] = substreams[buff[1]].Substring(0, substreams[buff[1]].Length - 1) + "/Wide)";
                            }
                            else
                            {
                                substreams[buff[1]] += "(Wide)";
                            }
                        }
                        if (buff[2] > 0)
                        {
                            if (substreams[buff[2]].Substring(substreams[buff[2]].Length - 1).Equals(")"))
                            {
                                substreams[buff[2]] = substreams[buff[2]].Substring(0, substreams[buff[2]].Length - 1) + "/Letterbox)";
                            }
                            else
                            {
                                substreams[buff[2]] += "(Letterbox)";
                            }
                        }
                        if (buff[3] > 0)
                        {
                            if (substreams[buff[3]].Substring(substreams[buff[3]].Length - 1).Equals(")"))
                            {
                                substreams[buff[3]] = substreams[buff[3]].Substring(0, substreams[buff[3]].Length - 1) + "/Pan&Scan)";
                            }
                            else
                            {
                                substreams[buff[3]] += "(Pan&Scan)";
                            }
                        }

                        if (bAddTypes && iCountStream == 2)
                        {
                            // only when the types should be added and the second track is in process
                            // first one is ignored because of the 0 stream ID which cannot be detected
                            int iID = 0;
                            if (buff[0] > 0)
                            {
                                iID = buff[0];
                                if (substreams[0].Substring(substreams[0].Length - 1).Equals(")"))
                                {
                                    substreams[0] = substreams[0].Substring(0, substreams[0].Length - 1) + "/4:3)";
                                }
                                else
                                {
                                    substreams[0] += "(4:3)";
                                }
                            }
                            if (buff[1] > 0 && (iID == 0 || iID == buff[1]))
                            {
                                iID = buff[1];
                                if (substreams[0].Substring(substreams[0].Length - 1).Equals(")"))
                                {
                                    substreams[0] = substreams[0].Substring(0, substreams[0].Length - 1) + "/Wide)";
                                }
                                else
                                {
                                    substreams[0] += "(Wide)";
                                }
                            }
                            if (buff[2] > 0 && (iID == 0 || iID == buff[2]))
                            {
                                iID = buff[2];
                                if (substreams[0].Substring(substreams[0].Length - 1).Equals(")"))
                                {
                                    substreams[0] = substreams[0].Substring(0, substreams[0].Length - 1) + "/Letterbox)";
                                }
                                else
                                {
                                    substreams[0] += "(Letterbox)";
                                }
                            }
                            if (buff[3] > 0 && (iID == 0 || iID == buff[3]))
                            {
                                iID = buff[3];
                                if (substreams[0].Substring(substreams[0].Length - 1).Equals(")"))
                                {
                                    substreams[0] = substreams[0].Substring(0, substreams[0].Length - 1) + "/Pan&Scan)";
                                }
                                else
                                {
                                    substreams[0] += "(Pan&Scan)";
                                }
                            }
                        }
                    }
                }

                if (bGetAllStreams)
                {
                    for (int i = 0; i < 32; i++)
                    {
                        if (String.IsNullOrEmpty(substreams[i]))
                        {
                            substreams[i] = "[" + String.Format("{0:00}", i) + "] - not detected";
                        }
                    }
                }
                else
                {
                    ArrayList arrList = new ArrayList();
                    foreach (string strItem in substreams)
                    {
                        if (!String.IsNullOrEmpty(strItem))
                        {
                            // remove trailing " - " if it exists
                            if (strItem.Substring(strItem.Length - 3).Equals(" - "))
                            {
                                arrList.Add(strItem.Substring(0, strItem.Length - 3).Trim());
                            }
                            else
                            {
                                arrList.Add(strItem.Trim());
                            }
                        }
                    }
                    substreams = new string[arrList.Count];
                    for (int i = 0; i < arrList.Count; i++)
                    {
                        substreams[i] = arrList[i].ToString();
                    }
                }

                fs.Close();
            }
            catch (Exception ex)
            {
                LogItem _oLog = MainForm.Instance.Log.Info("IFOparser");
                _oLog.LogValue("Error parsing ifo file " + FileName, ex.Message, ImageType.Error);
            }
            return(substreams);
        }