public void SwapsCorrectly(string expectedValue, SwapMode swapMode, string toConvert)
            {
                var bytes = toConvert.Select(c => (byte)c).ToArray().AsSpan();

                ByteSwapper.Swap(bytes, swapMode);

                var result = new string(bytes.ToArray().Select(b => (char)b).ToArray());

                Assert.AreEqual(expectedValue, result);
            }
Beispiel #2
0
        public byte[] GetByteArray()
        {
            this.InitialiseSendBuffer();
            this.CopyStructToByteArray(this.dataPck);
            crc = this.crcController.CalculateCrc(new ArraySegment <byte>(this.SendBuffer, 4, DataPckTypes.SendDataPckDataSize));
            var crcBytes = BitConverter.GetBytes(crc);

            if (!BitConverter.IsLittleEndian)
            {
                crcBytes = ByteSwapper.SwapBytes(crcBytes);
            }

            this.CopyCrcToSendBuffer(crcBytes);

            return(this.SendBuffer);
        }
Beispiel #3
0
		private void ProcessVOB()
		{
			try
			{
				DisableForm();
				List<IFOParse.VOB> vobs = null;
				IFOParse.ProgramChain pgc = null;
				List<IFOParse.Cell> cells = null;
				int selectedAudioTrack = 0;
				if (treeView1.SelectedNode.Tag.GetType() == typeof(FileInfo))
				{
					// treat a single vob file with no ifo file as all data
					// got single vob file
					FileInfo fi = (FileInfo)treeView1.SelectedNode.Tag;
					IFOParse.VOB v = new IFOParse.VOB(fi.FullName);
					vobs = new List<IFOParse.VOB>();
					vobs.Add(v);

					// create dummy cell list
					cells = new List<IFOParse.Cell>();
					IFOParse.Cell c = new IFOParse.Cell();
					c.FirstSector = 0;
					c.LastSector = (int)v.LastSector;
					cells.Add(c);
				}
				else if (treeView1.SelectedNode.Tag.GetType() == typeof(IFOParse.ProgramChain))
				{
					pgc = (IFOParse.ProgramChain)treeView1.SelectedNode.Tag;
					vobs = pgc.Title.VOBs;
					cells = pgc.Cells;
					// if we have multiple audio streams, allow the user to select which one to use
					if (pgc.Title.AudioFormat.Count > 1)
					{
						SelectAudio audioSelector = new SelectAudio(pgc.Title.AudioFormat);
						if (audioSelector.ShowDialog() == DialogResult.Cancel)
							return;
						selectedAudioTrack = audioSelector.SelectedSubstreamID;
					}
				}

				//string outputDir = "";
				#region Choose a file, default to last directory used
				string saveFile = "";
				saveFileDialog1.FileName = textBox2.Text + "-" + textBox4.Text + "-" + textBox3.Text + ".mpg";
				saveFileDialog1.FileName = new Utilities().MakeSafeFilename(saveFileDialog1.FileName);

				RegistryKey rk = Registry.LocalMachine.OpenSubKey(REGISTRY_KEY);
				if (rk != null)
				{
					string initialDir = rk.GetValue("DefaultDirectory").ToString();
					if (initialDir != null && Directory.Exists(initialDir))
						saveFileDialog1.InitialDirectory = initialDir;
				}
				DialogResult dr = saveFileDialog1.ShowDialog();
				if (dr == DialogResult.OK && File.Exists(saveFileDialog1.FileName))
				{
					dr = DialogResult.Cancel;
					// ask about overwriting
					if (MessageBox.Show(saveFileDialog1.FileName + " already exists.\nDo you want to replace it?", "Save As", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
					{
						dr = DialogResult.OK;
						File.Delete(saveFileDialog1.FileName);
					}
				}
				if (dr == DialogResult.OK)
				{
					saveFile = saveFileDialog1.FileName;
					FileInfo fi = new FileInfo(saveFile);
					try
					{
						RegistryKey saveKey = Registry.LocalMachine.CreateSubKey(REGISTRY_KEY);
						saveKey.SetValue("DefaultDirectory", fi.Directory.FullName);
						//outputDir = fi.Directory.FullName;
					}
					catch { }
				}
				else
				{
					SetProgress(0);
					SetStatusText("");
					EnableForm();
					thread = null;
					return;
				}
				#endregion

				int audioOffset = 0;
				int videoOffset = 0;
				string audio = null;
				string video = null;

				m_startTime = DateTime.Now;
				m_lastSecond = 0;

				try
				{
					SetProgress(0);
					byte[] buf = new byte[2048];
					long totalSectors = 0;
					long currentSector = 0;
					// find total number of sectors for all cells
					for (int cellNum = 0; cellNum < cells.Count; cellNum++)
					{
						IFOParse.Cell cell = cells[cellNum];
						totalSectors += cell.LastSector - cell.FirstSector;
					}

					SetStatusText("Reading from DVD...");
					for (int cellNum = 0; cellNum < cells.Count; cellNum++)
					{
						IFOParse.Cell cell = cells[cellNum];
						ulong updateInterval = 0;
						for (int sector = cell.FirstSector; sector <= cell.LastSector; sector++)
						{
							ReadSector(vobs, buf, sector);
							if (updateInterval++ % 10 == 0)
							{
								SetStatusText("Reading from DVD..." + Convert.ToInt32(100.0 * (Convert.ToDouble(currentSector) / Convert.ToDouble(totalSectors))) + "%");
								SetProgress(Convert.ToInt32(m_demuxCount * (Convert.ToDouble(currentSector) / Convert.ToDouble(totalSectors))));
							}
							currentSector++;
							uint code = ReadCode(buf, 0);
							if (code != BLOCK_START_CODE)
								continue;

							int i = 0x0e;
							ulong systemCode = ReadCode(buf, i);
							i += 4;
							UInt16 headerLength = ReadWord(buf, i);
							i += 2;

							switch (systemCode)
							{
								case AC3_DETECT_BYTES:
									//if (!inCell)
									//	break;
									//audPacks++;
									#region write non-mpeg audio data to temp file
									UInt16 flags = ReadWord(buf, i);
									i += 2;
									byte b = buf[i++];
									#region find ms offset
									if ((flags & 0xc000) == 0x8000 && (flags & 0xff) >= 0x80 && audioOffset == 0)
									{
										byte c = buf[i++];
										int offset = (c & 0x0e) << 29;
										offset += (ReadWord(buf, i) & 0xfffe) << 14;
										i += 2;
										offset += (ReadWord(buf, i) >> 1) & 0x7fff;
										i += 2;
										offset /= 90;
										i += b - 5;
										audioOffset = offset;
									}
									else
										i += b;
									#endregion
									byte substream = buf[i++];
									i++; // # frame headers
									UInt16 pointer = ReadWord(buf, i);
									i += 2;
									int t = substream;
									string name = t.ToString("000");
									if (t >= 0xA8) // nothing
										continue;
									else if (t >= 0xA0) // PCM
									{
										// http://dvd.sourceforge.net/dvdinfo/index.html
										name += ".wav";
										i++; // emph, mute, reserved, frame #
										byte details = buf[i++];
										i++; // dynamic range;

										// these seem to be zeroed out in my tests, ignore them
										int bitsPerSample = (details & 0xC0) >> 6;
										int sampleRate = (details & 0x30) >> 4;
										int numChannels = details & 0x07;
										b += 3;
									}
									else if (t >= 0x88) // DTS
										name += ".dts"; // dts audio will be ignored (most dvds are ac3, or at least have an ac3 track)
									else if (t >= 0x80) // AC3
										name += ".ac3";
									else
										continue;
									FileStream w = null;
									if (writers.ContainsKey(name))
										w = (FileStream)writers[name];
									else
									{
										w = File.Create(TempPath + name);
										writers[name] = w;
										if (name.EndsWith(".wav")) // leave room for wav header
											w.Seek(44, SeekOrigin.Begin);
									}
									//SaveData(w, buf, i, 2048 - i, t);
									SaveData(w, buf, i, (headerLength - 7 - b), t);
									#endregion
									break;
								case VID_DETECT_BYTES:
									//if (!inCell)
									//	break;
									//vidPacks++;
									#region write mpeg video to temp file
									flags = ReadWord(buf, i);
									i += 2;
									b = buf[i++];
									#region find ms offset
									if ((flags & 0xc000) == 0x8000 && (flags & 0xff) >= 0x80 && videoOffset == 0)
									{
										byte c = buf[i++];
										int offset = (c & 0x0e) << 29;
										offset += (ReadWord(buf, i) & 0xfffe) << 14;
										i += 2;
										offset += (ReadWord(buf, i) >> 1) & 0x7fff;
										i += 2;
										offset /= 90;
										i += b - 5;
										videoOffset = offset;
									}
									else
										i += b;
									#endregion
									string vname = "video.m2v";
									video = vname;
									FileStream vw = null;
									if (writers.ContainsKey(vname))
										vw = (FileStream)writers[vname];
									else
									{
										vw = File.Create(TempPath + vname);
										writers[vname] = vw;
									}
									//SaveData(vw, buf, i, 2048 - i, 1);
									SaveData(vw, buf, i, (headerLength - 3 - b), 1);
									#endregion
									break;
								case AUD_DETECT_BYTES:
									//if (!inCell)
									//	break;
									//audPacks++;
									#region write mpeg audio to temp file
									flags = ReadWord(buf, i);
									i += 2;
									b = buf[i++];
									#region find ms offset
									if ((flags & 0xc000) == 0x8000 && (flags & 0xff) >= 0x80 && audioOffset == 0)
									{
										byte c = buf[i++];
										int offset = (c & 0x0e) << 29;
										offset += (ReadWord(buf, i) & 0xfffe) << 14;
										i += 2;
										offset += (ReadWord(buf, i) >> 1) & 0x7fff;
										i += 2;
										offset /= 90;
										i += b - 5;
										audioOffset = offset;
									}
									else
										i += b;
									#endregion
									string aname = "vob.mp2";
									if (audio == null)
										audio = aname;
									FileStream aw = null;
									if (writers.ContainsKey(aname))
										aw = (FileStream)writers[aname];
									else
									{
										aw = File.Create(TempPath + aname);
										writers[aname] = aw;
									}
									//SaveData(aw, buf, i, 2048 - i, 0);
									SaveData(aw, buf, i, (headerLength - 3 - b), 1);
									#endregion
									break;
								case NAV_DETECT_BYTES:
									//navPacks++;
									#region find vobID and cellID
									int cellID = buf[0x422];
									int vobID = (buf[0x41f] << 8) + buf[0x420];
									//if (cellID == cell.CellID && vobID == cell.VobID)
									//	inCell = true;
									//else
									//	inCell = false;
									#endregion
									break;
								default:
									break;
							}

							if (m_run == false)
								return;
						}
					}
					SetProgress(m_demuxCount);
				}
				finally
				{
					if (bs != null)
						bs.TRMSFinalize();
					bs = null;
					foreach (string name in writers.Keys)
					{
						FileStream fs = (FileStream)writers[name];
						fs.Close();

						// determine the audio track to use by selecting the first one we encounter,
						// or the one the user selected if there is more than one
						// (if the audio is .mp2, it will already be set and we don't have to worry about the non-digit
						// name at this point)
						if (name.EndsWith(".m2v"))
							video = name;
						else if (audio == null && selectedAudioTrack == 0 && (name.EndsWith(".ac3") || name.EndsWith(".dts") || name.EndsWith(".wav") || name.EndsWith(".mp2"))) // select first audio track we encounter, unless otherwise directed
							audio = name;
						else if (audio == null && selectedAudioTrack == Convert.ToInt32(Path.GetFileNameWithoutExtension(name)))
							audio = name;

						// delete anything after the first audio and video streams in the file
						if (audio != null && name != video && name != audio)
							File.Delete(name);
					}
					writers.Clear();
					foreach (FileStream fs in readers.Values)
					{
						fs.Close();
					}
					readers.Clear();
				}

				int duration = 0;
				if (pgc != null)
					duration = pgc.Duration;
				if (audio == null) // don't process empty audio (will screw things up)
					return;
				audio = ConvertAudio(TempPath + audio, duration);
				if (audio == null)
					return;
				SetProgress(m_audioCount);

				DisableCancel();
				SetStatusText("Remuxing elementary mpeg streams...");
				FileInfo appPath = new FileInfo(Application.ExecutablePath);
				string mplexCommand = appPath.Directory + "\\mplex.exe";
				if (File.Exists(mplexCommand) == false)
					return;

				process = new Process();
				process.StartInfo.UseShellExecute = false;
				process.StartInfo.WorkingDirectory = Environment.CurrentDirectory;
				//process.StartInfo.RedirectStandardOutput = true;
				process.StartInfo.RedirectStandardError = true;
				process.StartInfo.FileName = mplexCommand;
				int AVOffset = Offset(cells, vobs);
				// format = MPEG2 (-f 3)
				// -V = VBR
				// -v 2 = verbose output
				// -O x = A/V offset
				// -S 0 = disable segment splitting
				// -o <file> = output to final output
				process.StartInfo.Arguments = String.Format("-f 3 -V -v 2 -O {0} -S 0 -o \"{1}\" \"{2}\" \"{3}\"",
					AVOffset,
					saveFile,
					TempPath + video,
					audio);
				process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
				process.StartInfo.CreateNoWindow = true;
				process.Start();
				string line;
				string muxBitrate = String.Empty;
				string muxStatus = String.Empty;
				int streams = 0;
				int overflowCount = 0;
				long lastSCR = 0;
				StreamReader sr = process.StandardError;
				DateTime lastMessage = DateTime.MinValue;
				while ((line = sr.ReadLine()) != null)
				{
					line = Regex.Replace(line, @"^[^\[]*\[[^\]]*\]\s+", ""); // get rid of process name at start of string
					if (m_run == false)
						return;
					else if(line.Contains("SCR="))
					{
						if (DateTime.Now < lastMessage.AddMilliseconds(50))
							continue;
						try
						{
							Match m = Regex.Match(line, @"\w\d:\s+SCR=(-?\d+)");
							if (m.Success)
							{
								// workaround for printf in windows truncating 64-bit SCR data
								long scr = Convert.ToInt64(m.Groups[1].Value);
								if(scr < lastSCR)
									overflowCount++;
								lastSCR = scr;
								scr += overflowCount * UInt32.MaxValue;

								// divide it by the CLOCK value to get number of seconds
								scr /= m_mplexMpegClock;

								if (pgc == null)
								{
									SetStatusText("Remuxing elementary mpeg streams...");
								}
								else
								{
									SetStatusText("Remuxing elementary mpeg streams..." + Convert.ToInt32(100.0 * (Convert.ToDouble(scr) / Convert.ToDouble(pgc.Duration))) + "%");
									SetProgress(m_audioCount + Convert.ToInt32((m_remuxCount - m_audioCount) * (Convert.ToDouble(scr) / Convert.ToDouble(pgc.Duration))));
								}
								lastMessage = DateTime.Now;
							}
						}
						catch { }
					}
					else if (line == "New sequence commences...")
						streams++;
					else if (line.StartsWith("MUX STATUS: "))
					{
						line = line.Replace("MUX STATUS: ", "");
						muxStatus = line;
					}
					else if (line.StartsWith("Average bit-rate"))
					{
						muxBitrate = line;
					}
				}
				process.WaitForExit();
				process = null;

				SetProgress(m_remuxCount);
				if (String.IsNullOrEmpty(muxBitrate) == false)
				{
					SetStatusText(muxBitrate);
					Thread.Sleep(500);
				}
				if(AVOffset != 0)
				{
					if(String.IsNullOrEmpty(muxStatus))
						muxStatus = "";
					else 
						muxStatus += " ";
					muxStatus += "used " + AVOffset + "ms AV offset";
				}
				if (String.IsNullOrEmpty(muxStatus) == false)
				{
					SetStatusText(muxStatus);
					Thread.Sleep(500);
				}
			}
			catch (ThreadAbortException)
			{
				try
				{
					if (process != null && process.HasExited == false)
						process.Kill();
				}
				catch { }
			}
			catch (Exception ex)
			{
				MessageBox.Show("Error: " + ex.Message);
			}
			finally
			{
				if (process != null && process.HasExited == false)
					process.Kill();
				EnableForm();
				thread = null;
				SetProgress(0);
				//SetStatusText("");
				SetETAText("");
				SetStatusText("");

				try
				{
					Directory.Delete(TempPath, true);
				}
				catch { }
			}
		}
Beispiel #4
0
		private void SaveData(FileStream fs, byte[] data, int offset, int len, int id)
		{
			//uint x=0xffffffff;
			int skip = 0;

			if(fs.Name.EndsWith(".wav")) // swap bytes in wav data
			{
				if(bs == null)
					bs = new ByteSwapper(fs);
				for(int i = offset + skip; i < offset + skip + len; i++)
					bs.NextByte(data[i]);
			}
			else
				fs.Write(data, offset + skip, len);
		}