public MXFSystemItem(MXFReader reader, MXFKLV headerKLV) : base(headerKLV, "SystemItem (CP)", KeyType.SystemItem) { this.m_eType = MXFObjectType.SystemItem; if (this.Key[12] == 0x14) { this.Key.Name = "SystemItem (GC)"; } reader.Seek(this.DataOffset); // Seek to the start of the data // Parse system bitmap this.SystemBitmap = (SystemBitmap)reader.ReadByte(); // Parse Content package rate byte rate = reader.ReadByte(); int rateIndex = (rate & 0x1E) >> 1; int[] rates = new int[16] { 0, 24, 25, 30, 48, 50, 60, 72, 75, 90, 96, 100, 120, 0, 0, 0 }; int rateNonDrop = 1; if (rateIndex < 16) { rateNonDrop = rates[rateIndex]; } this.PackageRate = rateNonDrop; if ((rate & 0x01) == 0x01) // 1.001 divider active? { this.PackageRate = this.PackageRate / 1.001; } // Parse Content Package Type byte type = reader.ReadByte(); this.StreamStatus = (SystemStreamStatus)((type & 0xE0) >> 5); this.LowLatencyMode = ((type & 0x10) == 0x10); this.TransferMode = (SystemTransferMode)((type & 0x0C) >> 2); this.TimingMode = (SystemTimingMode)(type & 0x03); this.ChannelHandle = reader.ReadUInt16(); this.ContinuityCount = reader.ReadUInt16(); this.SMPTE = reader.ReadULKey(); // Always read even if zero MXFTimeStamp creationTimeStamp = reader.ReadBCDTimeCode(this.PackageRate); this.CreationDate = creationTimeStamp.ToString(); this.UserDate = reader.ReadBCDTimeCode(this.PackageRate); this.UserDateFullFrameNb = this.UserDate.GetString(true); }
/// <summary> /// Copy constructor /// </summary> /// <param name="other"></param> public MXFTimeStamp(MXFTimeStamp other) { this.DropFrame = other.DropFrame; this.HasFields = other.HasFields; this.FrameRate = other.FrameRate; this.Frame = other.Frame; this.Second = other.Second; this.Minute = other.Minute; this.Hour = other.Hour; this.Day = other.Day; this.Month = other.Month; this.Year = other.Year; this.FullFrame = other.FullFrame; this.Frame = other.Frame; }
/// <summary> /// Compares two timestamps to check if they are the same /// </summary> /// <param name="other">The timestamp to be compared</param> /// <returns>True if the timestamps are the same</returns> public bool IsSame(MXFTimeStamp other) { if (this.Year == other.Year && this.Month == other.Month && this.Day == other.Day && this.Hour == other.Hour && this.Minute == other.Minute && this.Second == other.Second && this.FullFrame == other.FullFrame && this.FrameRate == other.FrameRate) { return(true); } return(false); }
/// <summary> /// Reads a BCD timecode /// </summary> /// <param name="frameRate"></param> /// <returns></returns> public MXFTimeStamp ReadBCDTimeCode(double frameRate) { // TODO If MJD is set, time is milliseconds since X byte type = this.ReadByte(); MXFTimeStamp timeStamp = new MXFTimeStamp(); timeStamp.ParseBCDTimeCode(this, frameRate); this.ReadByte(); // BG7 + BG8 // Read 8 dummy bytes (always zero) this.ReadUInt64(); return(timeStamp); }
/// <summary> /// Check the essence range /// </summary> /// <param name="file"></param> /// <param name="results"></param> protected void CheckUserDates(MXFFile file, List <MXFValidationResult> results) { List <MXFSystemItem> items = this.m_systemItems.OrderBy(a => a.ContinuityCount).ToList(); if (items.Count > 1) { MXFTimeStamp ts = new MXFTimeStamp(items.First().UserDate); if (ts != null) { MXFValidationResult valResult = new MXFValidationResult("System Items"); results.Add(valResult); // And directly add the results MXFTimeStamp tsLast = null; for (int n = 1; n < items.Count() - 1; n++) // Skip last one (always invalid??) { ts.Increase(); if (!items[n].UserDate.IsEmpty()) { if (!items[n].UserDate.IsSame(ts)) { valResult.SetError(string.Format("Invalid user date at offset {0} (was {1}, expected {2})!", items[n].Offset, items[n].UserDate, ts)); return; } tsLast = items[n].UserDate; } } if (tsLast != null) { valResult.SetSuccess(string.Format("UserDates are continious from {0} to {1}, at {2} fps!", items.First().UserDate, tsLast, ts.FrameRate)); } else { valResult.SetSuccess(string.Format("UserDates are continious!")); } } } }
public MXFCDPPacket(MXFReader reader) : base(reader) { UInt16 identifier = reader.ReadW(); if (identifier == 0x9669) { this.Length = reader.ReadB(); this.FrameRateE = (MXFCDFFrameRate)((reader.ReadB() & 0xF0) >> 4); switch (this.FrameRateE) { case MXFCDFFrameRate.Rate_24: this.FrameRate = 24; break; case MXFCDFFrameRate.Rate_24000_1001: this.FrameRate = 24000.0 / 1001.0; break; case MXFCDFFrameRate.Rate_25: this.FrameRate = 25; break; case MXFCDFFrameRate.Rate_30: this.FrameRate = 30; break; case MXFCDFFrameRate.Rate_30000_1001: this.FrameRate = 30000.0 / 1001.0; break; case MXFCDFFrameRate.Rate_50: this.FrameRate = 50; break; case MXFCDFFrameRate.Rate_60: this.FrameRate = 60; break; case MXFCDFFrameRate.Rate_60000_1001: this.FrameRate = 60000.0 / 1001.0; break; } byte options = reader.ReadB(); this.TimeCodePresent = ((options & 0x80) != 0); this.CCDataPresent = ((options & 0x40) != 0); this.SVCInfoPresent = ((options & 0x20) != 0); this.SVCInfoStart = ((options & 0x10) != 0); this.SVCInfoChange = ((options & 0x08) != 0); this.SVCInfoComplete = ((options & 0x04) != 0); this.CaptionServiceActive = ((options & 0x02) != 0); this.SequenceCounter = reader.ReadW(); byte count = 0; long endPos = this.Offset + this.Length; while (reader.Position < endPos) { identifier = reader.ReadB(); switch (identifier) { case 0x71: this.TimeCode = new MXFTimeStamp(); this.TimeCode.ParseSMPTE12M(reader, this.FrameRate.Value); break; case 0x72: count = (byte)(reader.ReadB() & 0x1F); for (int n = 0; n < count; n++) { this.AddChild(new MXFEntryCCData(reader)); } break; case 0x73: count = (byte)(reader.ReadB() & 0x0F); for (int n = 0; n < count; n++) { this.AddChild(new MXFEntrySVCInfo(reader)); } break; case 0x74: this.AddChild(new MXFCDPFooter(reader)); break; default: this.AddChild(new MXFCDPFuture(reader, (byte)identifier)); break; } } } }