예제 #1
0
        /// <summary>
        /// Adds the specified packet and automatically places it on the right track.
        /// If the track requires sorting it does so by reordering packets based on their timestamp.
        /// </summary>
        /// <param name="item">The item.</param>
        public void Add(ClosedCaptionPacket item)
        {
            CurrentNtscField = item.NtscField != 0 ? item.NtscField : 1;
            CurrentChannel   = item.Channel != 0 ? item.Channel : CurrentChannel;
            var targetCC = CC1;

            if (CurrentNtscField == 1)
            {
                if (CurrentChannel == 1)
                {
                    targetCC = CC1;
                }
                else
                {
                    targetCC = CC2;
                }
            }
            else
            {
                if (CurrentChannel == 1)
                {
                    targetCC = CC3;
                }
                else
                {
                    targetCC = CC4;
                }
            }

            var performSort = targetCC.Count != 0;

            if (targetCC.Count > 0 && targetCC.Last().Timestamp.Ticks <= item.Timestamp.Ticks)
            {
                performSort = false;
            }

            targetCC.Add(item);

            if (performSort)
            {
                targetCC.Sort();
            }
        }
예제 #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ClosedCaptionPacket"/> class.
        /// </summary>
        /// <param name="timestamp">The timestamp.</param>
        /// <param name="header">The header.</param>
        /// <param name="d0">The d0.</param>
        /// <param name="d1">The d1.</param>
        public ClosedCaptionPacket(TimeSpan timestamp, byte header, byte d0, byte d1)
        {
            D0 = DropParityBit(d0);
            D1 = DropParityBit(d1);

            NtscField = ClosedCaptionPacket.GetHeaderFieldType(header);
            Channel   = 0;
            Timestamp = timestamp;

            #region Header Checking

            if (HeaderHasMarkers(header) == false ||
                IsHeaderValidFalgSet(header) == false ||
                (NtscField == 0) ||
                (D0 == 0x00 && D1 == 0x00))
            {
                PacketType = CCPacketType.NullPad;
                return;
            }

            PacketType = CCPacketType.Unrecognized;

            #endregion

            #region Xds Packet Detection

            // XDS Parsing
            if ((D0 & 0x0F) == D0 && D0 != 0)
            {
                PacketType = CCPacketType.XdsClass;
                XdsClass   = (CCXdsClassType)D0;
                return;
            }

            #endregion

            #region Color Command Detection (Table 3)

            if ((D0 == 0x10 || D0 == 0x18) && (D1 >= 0x20 && D1 <= 0x2F))
            {
                Channel    = (D0 == 0x10) ? 1 : 2;
                PacketType = CCPacketType.Color;
                Color      = (CCColorType)D1;
                return;
            }

            if ((D0 == 0x17 || D0 == 0x1F) && (D1 >= 0x2D && D1 <= 0x2F))
            {
                Channel    = (D0 == 0x17) ? 1 : 2;
                PacketType = CCPacketType.Color;
                var colorValue = D1 << 16;
                Color = (CCColorType)colorValue;

                return;
            }

            #endregion

            #region Charset Select Packet Detection (Table 4)

            if ((D0 == 0x17 || D0 == 0x1F) && (D1 >= 0x24 && D1 <= 0x2A))
            {
                Channel    = (D0 == 0x17) ? 1 : 2;
                PacketType = CCPacketType.Charset;
                return;
            }

            #endregion

            #region MidRow Code Detection (Table 69)

            // Midrow Code Parsing
            if ((D0 == 0x11 || D0 == 0x19) && (D1 >= 0x20 && D1 <= 0x2F))
            {
                PacketType  = CCPacketType.MidRow;
                Channel     = D0 == 0x11 ? 1 : 2;
                MidRowStyle = (CCStyleType)D1;
                return;
            }

            #endregion

            #region Misc Command Detection (Table 70)

            // Screen command parsing
            if ((D0 == 0x14 || D0 == 0x1C) && (D1 >= 0x20 && D1 <= 0x2F))
            {
                PacketType  = CCPacketType.MiscCommand;
                MiscCommand = (CCMiscCommandType)D1;
                Channel     = (D0 == 0x14 || D0 == 0x1C) ? 1 : 2;
                return;
            }

            // Tab command Parsing
            if ((D0 == 0x17 || D0 == 0x1F) && (D1 >= 0x21 && D1 <= 0x23))
            {
                PacketType = CCPacketType.Tabs;
                Tabs       = D1 & 0x03;
                Channel    = D0 == 0x17 ? 1 : 2;
                return;
            }

            #endregion

            #region Preamble Command Detection (Table 71)

            // Preamble Parsing
            if ((D1 >= 0x40 && D1 <= 0x5F) || (D1 >= 0x60 && D1 <= 0x7F))
            {
                // Row 11 is different -- check for it
                if (D0 == 0x10 || D0 == 0x18)
                {
                    PacketType    = CCPacketType.Preamble;
                    Channel       = D0 == 0x10 ? 1 : 2;
                    PreambleRow   = 11;
                    PreambleStyle = (CCStyleType)(D1 - 0x20);
                    return;
                }

                var wasSet = false;
                if (D0 >= 0x11 && D0 <= 0x17)
                {
                    PacketType = CCPacketType.Preamble;
                    Channel    = 1;
                    wasSet     = true;
                }

                if (D0 >= 0x19 && D0 <= 0x1F)
                {
                    PacketType = CCPacketType.Preamble;
                    Channel    = 2;
                    wasSet     = true;
                }

                if (wasSet)
                {
                    if (D1 >= 0x40 && D1 <= 0x5F)
                    {
                        PreambleRow   = OddPreambleRows[D0];
                        PreambleStyle = (CCStyleType)(D1 - 0x20);
                    }
                    else
                    {
                        PreambleRow   = EvenPreambleRows[D0];
                        PreambleStyle = (CCStyleType)(D1 - 0x40);
                    }

                    return;
                }
            }

            #endregion

            #region Text Parsing (Table 5, 6, 7, 8, 9, 10, and 68 for ASCII Chars)

            PacketType = CCPacketType.Text;

            // Special North American character set
            if ((D0 == 0x11 || D0 == 0x19) && D1 >= 0x30 && D1 <= 0x3F)
            {
                if (SpecialNorthAmerican.ContainsKey(D1))
                {
                    Channel = (D0 == 0x11) ? 1 : 2;
                    Text    = SpecialNorthAmerican[D1];
                    return;
                }
            }

            if (D0 == 0x12 || D0 == 0x1A)
            {
                if (Spanish.ContainsKey(D1))
                {
                    Channel = 1;
                    Text    = Spanish[D1];
                    return;
                }

                if (French.ContainsKey(D1))
                {
                    Channel = 2;
                    Text    = French[D1];
                    return;
                }
            }

            if (D0 == 0x13 || D0 == 0x1B)
            {
                if (Portuguese.ContainsKey(D1))
                {
                    Channel = 1;
                    Text    = Portuguese[D1];
                    return;
                }

                if (German.ContainsKey(D1))
                {
                    Channel = 2;
                    Text    = German[D1];
                    return;
                }
            }

            // Basic North American character set (2 chars)
            if (D0 >= 0x20 && D0 <= 0x7F && (D1 == 0x00 || (D1 >= 0x20 && D1 <= 0x7F)))
            {
                Channel = 0;
                Text    = D1 == 0x00 ? $"{ToEia608Char(D0)}" : $"{ToEia608Char(D0)}{ToEia608Char(D1)}";
                return;
            }

            #endregion

            PacketType = CCPacketType.Unrecognized;
            Channel    = 0;
        }