Ejemplo n.º 1
0
        public TSPlaylistFile(
            BDROM bdrom,
            string name,
            List<TSStreamClip> clips)
        {
            BDROM = bdrom;
            Name = name;
            IsCustom = true;
            foreach (TSStreamClip clip in clips)
            {
                TSStreamClip newClip = new TSStreamClip(
                    clip.StreamFile, clip.StreamClipFile);

                newClip.Name = clip.Name;
                newClip.TimeIn = clip.TimeIn;
                newClip.TimeOut = clip.TimeOut;
                newClip.Length = newClip.TimeOut - newClip.TimeIn;
                newClip.RelativeTimeIn = TotalLength;
                newClip.RelativeTimeOut = newClip.RelativeTimeIn + newClip.Length;
                newClip.AngleIndex = clip.AngleIndex;
                newClip.Chapters.Add(clip.TimeIn);
                StreamClips.Add(newClip);

                if (newClip.AngleIndex > AngleCount)
                {
                    AngleCount = newClip.AngleIndex;
                }
                if (newClip.AngleIndex == 0)
                {
                    Chapters.Add(newClip.RelativeTimeIn);
                }
            }
            LoadStreamClips();
            IsInitialized = true;
        }
Ejemplo n.º 2
0
 public bool IsCompatible(TSStreamClip clip)
 {
     foreach (TSStream stream1 in StreamFile.Streams.Values)
     {
         if (clip.StreamFile.Streams.ContainsKey(stream1.PID))
         {
             TSStream stream2 = clip.StreamFile.Streams[stream1.PID];
             if (stream1.StreamType != stream2.StreamType)
             {
                 return false;
             }
         }
     }
     return true;
 }
Ejemplo n.º 3
0
        public void Scan(
            Dictionary<string, TSStreamFile> streamFiles,
            Dictionary<string, TSStreamClipFile> streamClipFiles)
        {
            FileStream fileStream = null;
            BinaryReader fileReader = null;

            try
            {
                Streams.Clear();
                StreamClips.Clear();

                fileStream = File.OpenRead(FileInfo.FullName);
                fileReader = new BinaryReader(fileStream);

                byte[] data = new byte[fileStream.Length];
                int dataLength = fileReader.Read(data, 0, data.Length);

                int pos = 0;

                FileType = ReadString(data, 8, ref pos);
                if (FileType != "MPLS0100" && FileType != "MPLS0200")
                {
                    throw new Exception(string.Format(
                        "Playlist {0} has an unknown file type {1}.",
                        FileInfo.Name, FileType));
                }

                int playlistOffset = ReadInt32(data, ref pos);
                int chaptersOffset = ReadInt32(data, ref pos);
                int extensionsOffset = ReadInt32(data, ref pos);

                // misc flags
                pos = 0x38;
                byte miscFlags = ReadByte(data, ref pos);

                // MVC_Base_view_R_flag is stored in 4th bit
                MVCBaseViewR = (miscFlags & 0x10) != 0;

                pos = playlistOffset;

                int playlistLength = ReadInt32(data, ref pos);
                int playlistReserved = ReadInt16(data, ref pos);
                int itemCount = ReadInt16(data, ref pos);
                int subitemCount = ReadInt16(data, ref pos);

                List<TSStreamClip> chapterClips = new List<TSStreamClip>();
                for (int itemIndex = 0; itemIndex < itemCount; itemIndex++)
                {
                    int itemStart = pos;
                    int itemLength = ReadInt16(data, ref pos);
                    string itemName = ReadString(data, 5, ref pos);
                    string itemType = ReadString(data, 4, ref pos);

                    TSStreamFile streamFile = null;
                    string streamFileName = string.Format(
                        "{0}.M2TS", itemName);
                    if (streamFiles.ContainsKey(streamFileName))
                    {
                        streamFile = streamFiles[streamFileName];
                    }
                    if (streamFile == null)
                    {
                        Debug.WriteLine(string.Format(
                            "Playlist {0} referenced missing file {1}.",
                            FileInfo.Name, streamFileName));
                    }

                    TSStreamClipFile streamClipFile = null;
                    string streamClipFileName = string.Format(
                        "{0}.CLPI", itemName);
                    if (streamClipFiles.ContainsKey(streamClipFileName))
                    {
                        streamClipFile = streamClipFiles[streamClipFileName];
                    }
                    if (streamClipFile == null)
                    {
                        throw new Exception(string.Format(
                            "Playlist {0} referenced missing file {1}.",
                            FileInfo.Name, streamFileName));
                    }

                    pos += 1;
                    int multiangle = (data[pos] >> 4) & 0x01;
                    int condition = data[pos] & 0x0F;
                    pos += 2;

                    int inTime = ReadInt32(data, ref pos);
                    if (inTime < 0) inTime &= 0x7FFFFFFF;
                    double timeIn = (double)inTime / 45000;

                    int outTime = ReadInt32(data, ref pos);
                    if (outTime < 0) outTime &= 0x7FFFFFFF;
                    double timeOut = (double)outTime / 45000;

                    TSStreamClip streamClip = new TSStreamClip(
                        streamFile, streamClipFile);

                    streamClip.Name = streamFileName; //TODO
                    streamClip.TimeIn = timeIn;
                    streamClip.TimeOut = timeOut;
                    streamClip.Length = streamClip.TimeOut - streamClip.TimeIn;
                    streamClip.RelativeTimeIn = TotalLength;
                    streamClip.RelativeTimeOut = streamClip.RelativeTimeIn + streamClip.Length;
                    StreamClips.Add(streamClip);
                    chapterClips.Add(streamClip);

                    pos += 12;
                    if (multiangle > 0)
                    {
                        int angles = data[pos];
                        pos += 2;
                        for (int angle = 0; angle < angles - 1; angle++)
                        {
                            string angleName = ReadString(data, 5, ref pos);
                            string angleType = ReadString(data, 4, ref pos);
                            pos += 1;

                            TSStreamFile angleFile = null;
                            string angleFileName = string.Format(
                                "{0}.M2TS", angleName);
                            if (streamFiles.ContainsKey(angleFileName))
                            {
                                angleFile = streamFiles[angleFileName];
                            }
                            if (angleFile == null)
                            {
                                throw new Exception(string.Format(
                                    "Playlist {0} referenced missing angle file {1}.",
                                    FileInfo.Name, angleFileName));
                            }

                            TSStreamClipFile angleClipFile = null;
                            string angleClipFileName = string.Format(
                                "{0}.CLPI", angleName);
                            if (streamClipFiles.ContainsKey(angleClipFileName))
                            {
                                angleClipFile = streamClipFiles[angleClipFileName];
                            }
                            if (angleClipFile == null)
                            {
                                throw new Exception(string.Format(
                                    "Playlist {0} referenced missing angle file {1}.",
                                    FileInfo.Name, angleClipFileName));
                            }

                            TSStreamClip angleClip =
                                new TSStreamClip(angleFile, angleClipFile);
                            angleClip.AngleIndex = angle + 1;
                            angleClip.TimeIn = streamClip.TimeIn;
                            angleClip.TimeOut = streamClip.TimeOut;
                            angleClip.RelativeTimeIn = streamClip.RelativeTimeIn;
                            angleClip.RelativeTimeOut = streamClip.RelativeTimeOut;
                            angleClip.Length = streamClip.Length;
                            StreamClips.Add(angleClip);
                        }
                        if (angles - 1 > AngleCount) AngleCount = angles - 1;
                    }

                    int streamInfoLength = ReadInt16(data, ref pos);
                    pos += 2;
                    int streamCountVideo = data[pos++];
                    int streamCountAudio = data[pos++];
                    int streamCountPG = data[pos++];
                    int streamCountIG = data[pos++];
                    int streamCountSecondaryAudio = data[pos++];
                    int streamCountSecondaryVideo = data[pos++];
                    int streamCountPIP = data[pos++];
                    pos += 5;

#if DEBUG
                    Debug.WriteLine(string.Format(
                        "{0} : {1} -> V:{2} A:{3} PG:{4} IG:{5} 2A:{6} 2V:{7} PIP:{8}", 
                        Name, streamFileName, streamCountVideo, streamCountAudio, streamCountPG, streamCountIG, 
                        streamCountSecondaryAudio, streamCountSecondaryVideo, streamCountPIP));
#endif

                    for (int i = 0; i < streamCountVideo; i++)
                    {
                        TSStream stream = CreatePlaylistStream(data, ref pos);
                        if (stream != null) PlaylistStreams[stream.PID] = stream;
                    }
                    for (int i = 0; i < streamCountAudio; i++)
                    {
                        TSStream stream = CreatePlaylistStream(data, ref pos);
                        if (stream != null) PlaylistStreams[stream.PID] = stream;
                    }
                    for (int i = 0; i < streamCountPG; i++)
                    {
                        TSStream stream = CreatePlaylistStream(data, ref pos);
                        if (stream != null) PlaylistStreams[stream.PID] = stream;
                    }
                    for (int i = 0; i < streamCountIG; i++)
                    {
                        TSStream stream = CreatePlaylistStream(data, ref pos);
                        if (stream != null) PlaylistStreams[stream.PID] = stream;
                    }
                    for (int i = 0; i < streamCountSecondaryAudio; i++)
                    {
                        TSStream stream = CreatePlaylistStream(data, ref pos);
                        if (stream != null) PlaylistStreams[stream.PID] = stream;
                        pos += 2;
                    }
                    for (int i = 0; i < streamCountSecondaryVideo; i++)
                    {
                        TSStream stream = CreatePlaylistStream(data, ref pos);
                        if (stream != null) PlaylistStreams[stream.PID] = stream;
                        pos += 6;
                    }
                    /*
                     * TODO
                     * 
                    for (int i = 0; i < streamCountPIP; i++)
                    {
                        TSStream stream = CreatePlaylistStream(data, ref pos);
                        if (stream != null) PlaylistStreams[stream.PID] = stream;
                    }
                    */

                    pos += itemLength - (pos - itemStart) + 2;
                }

                pos = chaptersOffset + 4;

                int chapterCount = ReadInt16(data, ref pos);

                for (int chapterIndex = 0;
                    chapterIndex < chapterCount;
                    chapterIndex++)
                {
                    int chapterType = data[pos+1];

                    if (chapterType == 1)
                    {
                        int streamFileIndex =
                            ((int)data[pos + 2] << 8) + data[pos + 3];

                        long chapterTime =
                            ((long)data[pos + 4] << 24) +
                            ((long)data[pos + 5] << 16) +
                            ((long)data[pos + 6] << 8) +
                            ((long)data[pos + 7]);

                        TSStreamClip streamClip = chapterClips[streamFileIndex];

                        double chapterSeconds = (double)chapterTime / 45000;

                        double relativeSeconds =
                            chapterSeconds -
                            streamClip.TimeIn +
                            streamClip.RelativeTimeIn;

                        // TODO: Ignore short last chapter?
                        if (TotalLength - relativeSeconds > 1.0)
                        {
                            streamClip.Chapters.Add(chapterSeconds);
                            this.Chapters.Add(relativeSeconds);
                        }
                    }
                    else
                    {
                        // TODO: Handle other chapter types?
                    }
                    pos += 14;
                }
            }
            finally
            {
                if (fileReader != null)
                {
                    fileReader.Close();
                }
                if (fileStream != null)
                {
                    fileStream.Close();
                }
            }
        }