(*************************************************************************
vStrip_gui: Graphical User Interface for vStrip-DLL
Copyright (C) 2001 [maven] (maven@maven.de)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0.8f:
- added dvd2avi support to gui
0.8e:
- fixed SetStart/-End LBA not always working on Cell-Level
0.8d:
- rearranged output screen to show dependency of outputs
- added chapters
- added video info (IFO)
- changed flags/type
- fixed incorrect fio_BUFFERSIZE
- better popup menu in ifo selection
- ask before adding menu vobs
- eta/throughput
0.8c:
- not much new on this side really... :)
0.8b:
- incorporated changed prototype/defines from command-line 0.8b
(maybe 1gb size is now detected correctly)
- fixed Key conversion (hex) when giving a Key
0.8a:
- udf file-selecter, new fileexit and filesize routines w/ udf support
0.8:
- incorporated console changes (different structures, udf, aspi)
0.7c:
- added audio & subp lang-support
- fixed swapped cell & vob id when saving settings (.vsc)
0.7b:
- added CELL LBA display
- renamed # of Sectors to End LBA (because that's what it was)
- added drag & drop support for files (ifo, vsc, lst, everything else -> added)
- added popup-menu to ifo-tree (to set start & end lba)
- improved Percentage/ProgressBar display when using start- and/or end-lba
0.7:
- added support for multiple outputs
- revised .vsc format (and loading & saving)
- reorganised things a bit to make room
- removed maximise button (hi alex!)
0.6ß:
- command-line support for files (.vsc loaded, others added)
- icon (could someone draw me a nice one, please?)
*************************************************************************)
unit MainForm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, StdCtrls, ExtCtrls, CheckLst, Math, vStrip, vStrip_Thread,
Registry, IniFiles, ShellApi, Menus, Grids;
const
vStripRegistryPath = '\Software\[maven]\vStrip_GUI';
type
TStreamInfo = record
save : Byte;
remap_to : Byte;
end;
TAStreamInfo = array[0..511] of TStreamInfo; // 0..255 streams, 256..511 substreams
TIFOProgramChain = record
NumCells : Integer;
Length : t_vs_time;
Cells : TPAVobCellID;
end;
TOutputInfo = record
FileName : string;
FileSize : Cardinal; // split
Flags : Cardinal;
end;
TvStripForm = class(TForm)
Input: TTabSheet;
IFO: TTabSheet;
Output: TTabSheet;
ButtonOpenVOB: TButton;
OpenVOBDialog: TOpenDialog;
ButtonRemoveVOB: TButton;
ButtonSortVOB: TButton;
ButtonDownVOB: TButton;
ButtonUpVOB: TButton;
OpenIFODialog: TOpenDialog;
ListViewFiles: TListView;
TreeViewIFO: TTreeView;
CheckListBoxStreams: TCheckListBox;
ListBoxRemap: TListBox;
ButtonClearVOB: TButton;
CheckBoxSubstreams: TCheckBox;
GroupBoxStreams: TGroupBox;
ButtonAllStreams: TButton;
ButtonNoStreams: TButton;
LabelRemap: TLabel;
GroupBoxOutputOptions: TGroupBox;
CheckBoxDemux: TCheckBox;
CheckBoxKeepGOPs: TCheckBox;
RadioGroupSplit: TRadioGroup;
CheckBoxAppend: TCheckBox;
CheckBoxAC3Header: TCheckBox;
CheckBoxPCMHeader: TCheckBox;
GroupBoxSplitSize: TGroupBox;
GroupBoxFileName: TGroupBox;
ButtonOutput: TButton;
EditFileName: TEdit;
SaveOutputDialog: TSaveDialog;
ButtonRun: TButton;
ProgressBar1: TProgressBar;
GroupBoxInputOptions: TGroupBox;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
EditStartLBA: TEdit;
EditEndLBA: TEdit;
EditMaxSync: TEdit;
GroupBoxDecrypt: TGroupBox;
EditPadGuess: TEdit;
EditSameGuess: TEdit;
EditPercentageGuess: TEdit;
EditKey: TEdit;
Label10: TLabel;
Label12: TLabel;
GroupBox1: TGroupBox;
EditIFOName: TEdit;
ButtonOpenIFO: TButton;
RadioGroupAngles: TRadioGroup;
GroupBoxCells: TGroupBox;
ListBoxVOBID: TListBox;
CheckListBoxCELLID: TCheckListBox;
ButtonIFOReset: TButton;
Label1: TLabel;
Label6: TLabel;
ListViewInfo: TListView;
SaveSettingsDialog: TSaveDialog;
OpenSettingsDialog: TOpenDialog;
GroupBox2: TGroupBox;
ButtonLoadSettings: TButton;
ButtonSaveSettings: TButton;
ComboBoxKeySearch: TComboBox;
Label7: TLabel;
GroupBox3: TGroupBox;
ComboBoxFrameRate: TComboBox;
Label5: TLabel;
Label8: TLabel;
ComboBoxAspectRatio: TComboBox;
RadioGroupOutputs: TRadioGroup;
ComboBoxFileSize: TComboBox;
PopupMenuIFO: TPopupMenu;
SetStartLBA: TMenuItem;
SetEndLBA: TMenuItem;
GroupBoxIFOAudio: TGroupBox;
ListBoxIFOAudio: TListBox;
GroupBoxIFOSub: TGroupBox;
ListBoxIFOSub: TListBox;
CheckBoxIsVOB: TCheckBox;
ComboBoxASPI: TComboBox;
ButtonUDF: TButton;
CheckBoxDemacro: TCheckBox;
GroupBoxIFOVideo: TGroupBox;
EditIFOVideo: TEdit;
SetStartEndLBA: TMenuItem;
ETA: TTabSheet;
GroupBoxETA: TGroupBox;
EditETA: TEdit;
GroupBoxSpeed: TGroupBox;
EditKS: TEdit;
Sheets: TPageControl;
CheckBoxDVD2AVI: TCheckBox;
procedure ButtonOpenVOBClick(Sender: TObject);
procedure ButtonRemoveVOBClick(Sender: TObject);
procedure ButtonSortVOBClick(Sender: TObject);
procedure ButtonUpVOBClick(Sender: TObject);
procedure ButtonDownVOBClick(Sender: TObject);
procedure ButtonOpenIFOClick(Sender: TObject);
procedure ListViewFilesCompare(Sender: TObject; Item1,
Item2: TListItem; Data: Integer; var Compare: Integer);
procedure FormCreate(Sender: TObject);
procedure ButtonRunClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure ButtonClearVOBClick(Sender: TObject);
procedure ListBoxRemapClick(Sender: TObject);
procedure CheckBoxSubstreamsClick(Sender: TObject);
procedure ButtonAllStreamsClick(Sender: TObject);
procedure ButtonNoStreamsClick(Sender: TObject);
procedure CheckBoxDemuxClick(Sender: TObject);
procedure EditFileSizeKeyPress(Sender: TObject; var Key: Char);
procedure ButtonOutputClick(Sender: TObject);
procedure EditKeyKeyPress(Sender: TObject; var Key: Char);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure ButtonIFOResetClick(Sender: TObject);
procedure ListBoxVOBIDClick(Sender: TObject);
procedure CheckListBoxCELLIDClickCheck(Sender: TObject);
procedure TreeViewIFOChange(Sender: TObject; Node: TTreeNode);
procedure CheckListBoxStreamsClick(Sender: TObject);
procedure ButtonSaveSettingsClick(Sender: TObject);
procedure ButtonLoadSettingsClick(Sender: TObject);
procedure EditFileNameChange(Sender: TObject);
procedure RadioGroupOutputsClick(Sender: TObject);
procedure TreeViewIFOContextPopup(Sender: TObject; MousePos: TPoint;
var Handled: Boolean);
procedure SetStartLBAClick(Sender: TObject);
procedure SetEndLBAClick(Sender: TObject);
procedure ButtonUDFClick(Sender: TObject);
procedure SetStartEndLBAClick(Sender: TObject);
procedure CheckBoxKeepGOPsClick(Sender: TObject);
private
data: t_vs_data;
streams, substreams: ta_vs_streamflags;
stream_ofs: Integer;
output_mask: Byte;
outputs: array[0..inb_MAX_OUTPUT - 1] of TOutputInfo;
num_output, cur_output: Integer;
stream_info: TAStreamInfo;
cell_list: TPAVobCellID;
num_cell: Integer;
KeepCells: array[0..255, 0..255, 0..1] of Boolean; // 0 display, 1 keep
ResetKeepCells: Boolean;
NumIFOChains: Integer;
IFOChainIdx: Integer;
IFOChains: array of TIFOProgramChain;
PopupMenuItem: TTreeNode;
VSThread: TVSThread;
VSThreadActive: Boolean;
procedure ParseCardinal(s: String; initial_value: Cardinal; var target: Cardinal);
procedure LoadInitialDirectory(dlg: TOpenDialog; regname: String);
procedure SaveInitialDirectory(dlg: TOpenDialog; regname: String; FileName: String);
procedure LoadSettings(FName: String);
procedure SaveSettings(FName: String);
procedure AddTime(var sum: array of Byte; b: array of Byte);
procedure ParseIFO(FileName: String);
procedure UpdateFileName(Name: String; OP: TRadioGroup; cur: Integer; var num: Integer);
procedure GetOutputSettings(var op: TOutputInfo);
procedure PutOutputSettings(op: TOutputInfo);
function AddFile(Name: String): Boolean;
procedure OnVSThreadTerminate(Sender: TObject);
procedure WMDropFiles(var m: TMessage); message WM_DROPFILES;
public
{ Public-Deklarationen }
function GetStreamDescription(Idx: Byte; SubStream: Boolean): String;
end;
var
vStripForm: TvStripForm;
implementation
uses UDFSel;
{$R *.DFM}
procedure TvStripForm.ParseCardinal(s: String; initial_value: Cardinal; var target: Cardinal);
var
i: Cardinal;
j: Integer;
begin
target := initial_value;
if (s <> '') then begin
Val(s, i, j);
if (j = 0) then
target := i;
end;
end;
procedure TvStripForm.LoadInitialDirectory(dlg: TOpenDialog; regname: String);
var
reg: TRegistry;
begin
reg := TRegistry.Create(KEY_READ);
try
if (reg.OpenKey(regname, False)) then begin
if (reg.ValueExists(dlg.Name)) then
dlg.InitialDir := reg.ReadString(dlg.Name);
reg.CloseKey();
end;
finally
reg.Free();
end;
end;
procedure TvStripForm.SaveInitialDirectory(dlg: TOpenDialog; regname: String; FileName: String);
var
reg: TRegistry;
begin
reg := TRegistry.Create(KEY_WRITE);
try
if (reg.OpenKey(regname, True)) then begin
reg.WriteString(dlg.Name, ExtractFileDir(FileName));
reg.CloseKey();
end;
finally
reg.Free();
end;
end;
procedure TvStripForm.LoadSettings(FName: String);
var
ini: TMemIniFile;
i, j, k, l, m: Integer;
SaveSaveStreams: Boolean;
OrMask, AndMask: Byte;
begin
ini := TMemIniFile.Create(FName);
// input
ListViewFiles.Items.Clear();
k := ini.ReadInteger('Input', 'NumFiles', 0);
for i := 0 to k - 1 do
AddFile(ini.ReadString('Input', 'F' + IntToStr(i), ''));
EditStartLBA.Text := ini.ReadString('Input', 'OfsPackets', '');
EditEndLBA.Text := ini.ReadString('Input', 'NumPackets', '');
EditMaxSync.Text := ini.ReadString('Input', 'MaxSync', '2048');
{$IFDEF vs_DECRYPT}
EditPadGuess.Text := ini.ReadString('Input', 'PadGuess', '2');
EditSameGuess.Text := ini.ReadString('Input', 'SameGuess', '2');
EditPercentageGuess.Text := ini.ReadString('Input', 'PercentageGuess', '75');
EditKey.Text := ini.ReadString('Input', 'Key', '');
ComboBoxKeySearch.ItemIndex := ini.ReadInteger('Input', 'KeySearch', 0);
{$ENDIF}
ComboBoxASPI.ItemIndex := ini.ReadInteger('Input', 'ASPIMode', 0);
CheckBoxIsVOB.Checked := ini.ReadBool('Input', 'IsVOB', true);
// ifo
ButtonIFOResetClick(nil);
EditIFOName.Text := ini.ReadString('IFO', 'IFOName', '');
if (EditIFOName.Text <> '') then
ParseIFO(EditIFOName.Text);
k := ini.ReadInteger('IFO', 'NumKeepCells', 0);
if (k = 65536) then begin
for i := 0 to 255 do
for j := 0 to 255 do
KeepCells[i, j, 1] := True
end else begin
for i := 0 to 255 do
for j := 0 to 255 do
KeepCells[i, j, 1] := False;
for i := 0 to k - 1 do begin
j := ini.ReadInteger('IFO', 'K' + IntToStr(i), -1);
if (j <> -1) then
KeepCells[j and $ff, j shr 8, 1] := True;
end;
end;
k := ini.ReadInteger('IFO', 'IFOChainIdx', -1);
if (k <> -1) then begin // select IFOChainIdx
if (k < NumIFOChains) then begin
for i := 0 to TreeViewIFO.Items.Count - 1 do with TreeViewIFO.Items[i] do
if ((Parent = nil) and (Integer(Data) = k)) then begin
IFOChainIdx := -1;
ResetKeepCells := False;
TreeViewIFO.Selected := TreeViewIFO.Items[i];
ResetKeepCells := True;
break;
end;
end;
end;
if (RadioGroupAngles.Enabled) then begin
i := ini.ReadInteger('IFO', 'Angles', -1);
if ((i <> -1) and (i < RadioGroupAngles.Items.Count)) then
RadioGroupAngles.ItemIndex := i;
end;
// output
CheckBoxDemacro.Checked := ini.ReadBool('Output', 'Demacro', True);
ComboBoxFrameRate.ItemIndex := ini.ReadInteger('Output', 'FrameRate', 0);
ComboBoxAspectRatio.ItemIndex := ini.ReadInteger('Output', 'AspectRatio', 0);
RadioGroupOutputs.Items.Clear();
num_output := ini.ReadInteger('Output', 'NumOutputs', 0);
k := 0;
for i := 0 to num_output do begin
RadioGroupOutputs.Items.Append('Output ' + IntToStr(k));
outputs[i].FileName := ini.ReadString('Output' + IntToStr(i), 'FileName', '');
j := ini.ReadInteger('Output' + IntToStr(i), 'FileSize', 0);
outputs[i].FileSize := j * ((1 shl 20) div fio_BUFFER_SIZE);
with outputs[i] do begin
flags := 0;
if (ini.ReadBool('Output' + IntToStr(i), 'Append', False)) then
flags := flags or vso_APPEND;
if (ini.ReadBool('Output' + IntToStr(i), 'Demux', False)) then
flags := flags or vso_DEMUX;
if (ini.ReadBool('Output' + IntToStr(i), 'AC3Header', False)) then
flags := flags or vso_KEEP_AC3_IDENT_BYTES;
if (ini.ReadBool('Output' + IntToStr(i), 'PCMHeader', False)) then
flags := flags or vso_KEEP_PCM_IDENT_BYTES;
if (ini.ReadBool('Output' + IntToStr(i), 'KeepGOPs', False)) then
flags := flags or vso_ONLY_KEEP_GOPS;
if (ini.ReadBool('Output' + IntToStr(i), 'DVD2AVI', False)) then
flags := flags or vso_DVD2AVI;
j := ini.ReadInteger('Output' + IntToStr(i), 'Split', 0);
case j of
1: flags := flags or vso_SPLIT_VOBID;
2: flags := flags or vso_SPLIT_CELLID;
end;
end;
SaveSaveStreams := ini.ReadBool('Output' + IntToStr(i), 'SaveSaveStreams', False);
// init masks
if (SaveSaveStreams) then begin
OrMask := $00;
AndMask := Byte(not (1 shl i));
end else begin
OrMask := 1 shl i;
AndMask := $ff;
end;
for l := 0 to 511 do
stream_info[l].save := (stream_info[l].save or OrMask) and AndMask;
// saved masks
if (not SaveSaveStreams) then begin
OrMask := $00;
AndMask := Byte(not (1 shl i));
end else begin
OrMask := 1 shl i;
AndMask := $ff;
end;
j := ini.ReadInteger('Output' + IntToStr(i), 'NumSaveStreams', 0);
for l := 0 to j - 1 do begin
m := ini.ReadInteger('Output' + IntToStr(i), 'S' + IntToStr(l), 0);
stream_info[m].save := (stream_info[m].save or OrMask) and AndMask;
end;
Inc(k);
end;
cur_output := 0;
PutOutputSettings(outputs[0]); // these will be copied on the next line
RadioGroupOutputs.ItemIndex := 0;
UpdateFileName(outputs[0].FileName, RadioGroupOutputs, 0, num_output); // empty one to RadioGroup if neccessary
j := ini.ReadInteger('Output', 'NumRemaps', 0);
for i := 0 to j - 1 do begin
k := ini.ReadInteger('Output', 'R' + IntToStr(i), 0);
stream_info[k and $1ff].remap_to := k shr 9;
end;
CheckBoxSubStreams.Checked := False;
for i := 0 to 255 do begin
CheckListBoxStreams.Checked[i] := (stream_info[i].save and output_mask) <> 0;
CheckListBoxStreams.Items.Strings[i] := GetStreamDescription(i, False);
end;
CheckListBoxStreams.ItemIndex := -1;
ListBoxRemap.ItemIndex := -1;
stream_ofs := 0;
RadioGroupOutputsClick(nil);
ini.Free();
end;
procedure TvStripForm.SaveSettings(FName: String);
var
ini: TMemIniFile;
i, j, k, l: Integer;
SaveSaveStreams: Boolean;
Mask, MaxMask: Byte;
begin
ini := TMemIniFile.Create(FName);
ini.Clear();
// input
ini.WriteInteger('Input', 'NumFiles', ListViewFiles.Items.Count);
for i := 0 to ListViewFiles.Items.Count - 1 do
ini.WriteString('Input', 'F' + IntToStr(i), ListViewFiles.Items[i].Caption);
if (EditStartLBA.Text <> '') then
ini.WriteString('Input', 'OfsPackets', EditStartLBA.Text);
if (EditEndLBA.Text <> '') then
ini.WriteString('Input', 'NumPackets', EditEndLBA.Text);
if (EditMaxSync.Text <> '') then
ini.WriteString('Input', 'MaxSync', EditMaxSync.Text);
{$IFDEF vs_DECRYPT}
if (EditPadGuess.Text <> '') then
ini.WriteString('Input', 'PadGuess', EditPadGuess.Text);
if (EditSameGuess.Text <> '') then
ini.WriteString('Input', 'SameGuess', EditSameGuess.Text);
if (EditPercentageGuess.Text <> '') then
ini.WriteString('Input', 'PercentageGuess', EditPercentageGuess.Text);
if (EditKey.Text <> '') then
ini.WriteString('Input', 'Key', EditKey.Text);
ini.WriteInteger('Input', 'KeySearch', ComboBoxKeySearch.ItemIndex);
{$ENDIF}
ini.WriteInteger('Input', 'ASPIMode', ComboBoxASPI.ItemIndex);
ini.WriteBool('Input', 'IsVOB', CheckBoxIsVOB.Checked);
// ifo
ini.WriteString('IFO', 'IFOName', EditIFOName.Text);
if (IFOChainIdx <> -1) then
ini.WriteInteger('IFO', 'IFOChainIdx', IFOChainIdx);
k := 0;
for i := 0 to 255 do
for j := 0 to 255 do
if (KeepCells[i, j, 1]) then
Inc(k);
ini.WriteInteger('IFO', 'NumKeepCells', k);
if ((k <> 0) and (k <> 256 * 256)) then begin
k := 0;
for i := 0 to 255 do
for j := 0 to 255 do
if (KeepCells[i, j, 1]) then begin
ini.WriteInteger('IFO', 'K' + IntToStr(k), i or (j shl 8)); // vob_id upper byte
Inc(k);
end;
end;
if (RadioGroupAngles.Enabled) then
ini.WriteInteger('IFO', 'Angles', RadioGroupAngles.ItemIndex);
// output
ini.WriteBool('Output', 'Demacro', CheckBoxDemacro.Checked);
ini.WriteInteger('Output', 'FrameRate', ComboBoxFrameRate.ItemIndex);
ini.WriteInteger('Output', 'AspectRatio', ComboBoxAspectRatio.ItemIndex);
GetOutputSettings(outputs[cur_output]);
j := 0;
for i := 0 to num_output do
if (outputs[i].FileName <> '') then
Inc(j);
ini.WriteInteger('Output', 'NumOutputs', j);
j := 0;
MaxMask := 0;
for i := 0 to num_output do
if (outputs[i].FileName <> '') then with outputs[i] do begin
MaxMask := MaxMask or (1 shl i);
ini.WriteString('Output' + IntToStr(j), 'FileName', FileName);
ini.WriteInteger('Output' + IntToStr(j), 'FileSize', FileSize div ((1 shl 20) div fio_BUFFER_SIZE));
k := 0;
if ((flags and vso_SPLIT_VOBID) <> 0) then
k := 1
else if ((flags and vso_SPLIT_CELLID) <> 0) then
k := 2;
ini.WriteInteger('Output' + IntToStr(j), 'Split', k);
ini.WriteBool('Output' + IntToStr(j), 'Append', (flags and vso_APPEND) <> 0);
ini.WriteBool('Output' + IntToStr(j), 'Demux', (flags and vso_DEMUX) <> 0);
ini.WriteBool('Output' + IntToStr(j), 'AC3Header', (flags and vso_KEEP_AC3_IDENT_BYTES) <> 0);
ini.WriteBool('Output' + IntToStr(j), 'PCMHeader', (flags and vso_KEEP_PCM_IDENT_BYTES) <> 0);
ini.WriteBool('Output' + IntToStr(j), 'KeepGOPs', (flags and vso_ONLY_KEEP_GOPS) <> 0);
ini.WriteBool('Output' + IntToStr(j), 'DVD2AVI', (flags and vso_DVD2AVI) <> 0);
Mask := 1 shl i;
k := 0;
for l := 0 to 511 do
if ((stream_info[l].save and Mask) <> 0) then
Inc(k);
SaveSaveStreams := k < 256;
ini.WriteBool('Output' + IntToStr(j), 'SaveSaveStreams', SaveSaveStreams);
if (not SaveSaveStreams) then begin
ini.WriteInteger('Output' + IntToStr(j), 'NumSaveStreams', 512 - k);
k := 0;
for l := 0 to 511 do with stream_info[l] do
if ((save and Mask) = 0) then begin
ini.WriteInteger('Output' + IntToStr(j), 'S' + IntToStr(k), l);
Inc(k);
end;
end else begin
ini.WriteInteger('Output' + IntToStr(j), 'NumSaveStreams', k);
k := 0;
for l := 0 to 511 do with stream_info[l] do
if ((save and Mask) <> 0) then begin
ini.WriteInteger('Output' + IntToStr(j), 'S' + IntToStr(k), l);
Inc(k);
end;
end;
Inc(j);
end;
j := 0;
for i := 0 to 511 do with stream_info[i] do
if (((save and MaxMask) <> 0) and (remap_to <> (i and 255))) then
Inc(j);
ini.WriteInteger('Output', 'NumRemaps', j);
j := 0;
for i := 0 to 511 do with stream_info[i] do
if (((save and MaxMask) <> 0) and (remap_to <> (i and 255))) then begin
ini.WriteInteger('Output', 'R' + IntToStr(j), i + (Ord(remap_to) shl 9));
Inc(j);
end;
ini.UpdateFile();
ini.Free();
end;
procedure TvStripForm.AddTime(var sum: array of Byte; b: array of Byte);
var
i: Integer;
max_f: Integer;
begin
for i := Low(sum) to High(sum) do
Inc(sum[i], (b[i] and DVD_TIME_AND));
max_f := 25;
if ((b[3] and (not DVD_TIME_AND)) = 192) then
max_f := 30;
if (sum[3] >= max_f) then begin
Dec(sum[3], max_f);
Inc(sum[2]);
end;
if (sum[2] >= 60) then begin // seconds
Dec(sum[2], 60);
Inc(sum[1]);
end;
if (sum[1] >= 60) then begin // minutes
Dec(sum[1], 60);
Inc(sum[0]);
end;
end;
procedure TvStripForm.ParseIFO(FileName: String);
var
i, j, k: Integer;
LastChapter: Integer;
ifo_handle, ifo_flags: Cardinal;
it, ch: TTreeNode;
ctime: array[0..3] of Byte;
s: String;
begin
TreeViewIFO.Items.Clear();
IFOChainIdx := -1;
RadioGroupAngles.Items.Clear();
RadioGroupAngles.Enabled := False;
ListBoxIFOAudio.Items.Clear();
ListBoxIFOSub.Items.Clear();
for i := 0 to NumIFOChains - 1 do
if (IFOChains[i].Cells <> Nil) then begin
FreeMem(IFOChains[i].Cells);
IFOChains[i].Cells := Nil;
end;
SetLength(IFOChains, 0);
NumIFOChains := 0;
it := nil;
ifo_flags := 0;
case ComboBoxASPI.ItemIndex of
0: ifo_flags := ifo_flags + fio_USE_ASPI;
1: ifo_flags := ifo_flags + fio_USE_ASPI + vs_PREFER_ASPI;
end;
ifo_handle := ifoOpen(PChar(EditIFOName.Text), ifo_flags);
if (ifo_handle <> 0) then begin
EditIFOVideo.Text := ifoGetVideoDesc(ifo_handle);
j := ifoGetNumAudio(ifo_handle);
for i := 0 to j - 1 do
ListBoxIFOAudio.Items.Add(Format('%d. %s', [i, ifoGetAudioDesc(ifo_handle, i)]));
j := ifoGetNumSubPic(ifo_handle);
for i := 0 to j - 1 do
ListBoxIFOSub.Items.Add(Format('%d. %s', [i, ifoGetSubPicDesc(ifo_handle, i)]));
with TreeViewIFO.Items do begin
BeginUpdate();
NumIFOChains := ifoGetNumPGCI(ifo_handle);
SetLength(IFOChains, NumIFOChains);
for i := 0 to NumIFOChains - 1 do with IFOChains[i] do begin
NumCells := ifoGetPGCIInfo(ifo_handle, i, Length);
it := AddObject(nil, Format('%u. Length: %u:%.2u:%.2u:%.2u in %d cell(s)', [i, Length[0], Length[1], Length[2], Length[3], NumCells]), Pointer(i));
GetMem(Cells, NumCells * SizeOf(t_vs_vobcellid));
ifoGetPGCICells(ifo_handle, i, @Cells^[0]);
ch := it;
LastChapter := -1;
for j := 0 to NumCells - 1 do with Cells[j] do begin
if (chapter <> LastChapter) then begin
ctime[0] := 0; ctime[1] := 0; ctime[2] := 0; ctime[3] := 0;
k := j;
while ((k < NumCells) and (Cells[k].chapter = chapter)) do begin
AddTime(ctime, Cells[k].time);
Inc(k);
end;
ch := AddChildObject(it, Format('%u. Chapter (%u:%.2u:%.2u:%.2u)',
[chapter, ctime[0], ctime[1], ctime[2], ctime[3]]), Pointer(j));
LastChapter := chapter;
end;
s := Format('%u. V: %.3u/C: %.3u', [j, vob_id, cell_id]);
if (angle <> $11) then
s := s + Format(' (%u/%u)', [angle and $f, angle shr 4]);
s := s + Format(' [@LBA %u - %u]', [start_lba, end_lba]);
AddChildObject(ch, s, Pointer(j));
end;
end;
if ((it <> nil) and (NumIFOChains = 1)) then
TreeViewIFO.Selected := it;
EndUpdate();
end;
ifoClose(ifo_handle);
end else
MessageDlg('vStrip could not read/parse the IFO-File', mtError, [mbOK], 0);
end;
procedure TvStripForm.UpdateFileName(Name: String; OP: TRadioGroup; cur: Integer; var num: Integer);
var
i: Integer;
f: Boolean;
begin
if (Name <> '') then begin // add if not one free
outputs[cur].FileName := Name;
f := False;
for i := 0 to num do
if (outputs[i].FileName = '') then
f := True;
if ((not f) and (num < inb_MAX_OUTPUT - 1)) then begin
Inc(num);
OP.Items.Append('Output ' + IntToStr(num));
end;
end else begin // remove if last
if ((num > 1) and ((cur = num) or (outputs[num].FileName = ''))) then begin
OP.Items.Delete(OP.Items.Count - 1);
Dec(Num);
end;
end;
end;
procedure TvStripForm.GetOutputSettings(var op: TOutputInfo);
begin
op.FileName := EditFileName.Text;
if (ComboBoxFileSize.Text = '') then
op.FileSize := 0
else begin
ParseCardinal(ComboBoxFileSize.Text, 0, op.FileSize);
op.FileSize := op.FileSize * ((1 shl 20) div fio_BUFFER_SIZE);
end;
op.flags := 0;
case RadioGroupSplit.ItemIndex of
1: op.flags := op.flags + vso_SPLIT_VOBID;
2: op.flags := op.flags + vso_SPLIT_CELLID;
end;
if (CheckBoxDemux.Checked) then begin
op.flags := op.flags + vso_DEMUX;
if (CheckBoxAC3Header.Checked) then
op.flags := op.flags + vso_KEEP_AC3_IDENT_BYTES;
if (CheckBoxPCMHeader.Checked) then
op.flags := op.flags + vso_KEEP_PCM_IDENT_BYTES;
end;
if (CheckBoxKeepGOPs.Checked) then
op.flags := op.flags + vso_ONLY_KEEP_GOPS;
if (CheckBoxDVD2AVI.Checked) then
op.flags := op.flags + vso_DVD2AVI;
if (CheckBoxAppend.Checked) then
op.flags := op.flags + vso_APPEND;
end;
procedure TvStripForm.PutOutputSettings(op: TOutputInfo);
begin
EditFileName.Text := op.FileName;
if (op.FileSize = 0) then
ComboBoxFileSize.Text := ''
else
ComboBoxFileSize.Text := IntToStr(op.FileSize div ((1 shl 20) div fio_BUFFER_SIZE));
if ((op.flags and vso_SPLIT_VOBID) <> 0) then
RadioGroupSplit.ItemIndex := 1
else if ((op.flags and vso_SPLIT_CELLID) <> 0) then
RadioGroupSplit.ItemIndex := 2
else
RadioGroupSplit.ItemIndex := 0;
CheckBoxDemux.Checked := (op.flags and vso_DEMUX) <> 0;
CheckBoxAC3Header.Checked := (op.flags and vso_KEEP_AC3_IDENT_BYTES) <> 0;
CheckBoxAC3Header.Enabled := CheckBoxDemux.Checked;
CheckBoxPCMHeader.Checked := (op.flags and vso_KEEP_PCM_IDENT_BYTES) <> 0;
CheckBoxPCMHeader.Enabled := CheckBoxDemux.Checked;
CheckBoxKeepGOPs.Checked := (op.flags and vso_ONLY_KEEP_GOPS) <> 0;
CheckBoxDVD2AVI.Checked := (op.flags and vso_DVD2AVI) <> 0;
CheckBoxAppend.Checked := (op.flags and vso_APPEND) <> 0;
end;
function TvStripForm.AddFile(Name: String): Boolean;
var
it: TListItem;
s: String;
sl: TextFile;
ignore: Boolean;
begin
Result := False;
if ((Name <> '') and uFileExists(Name)) then begin
if (AnsiCompareFileName(ExtractFileExt(Name), '.VSC') = 0) then begin
LoadSettings(Name);
end else if (AnsiCompareFileName(ExtractFileExt(Name), '.IFO') = 0) then begin
EditIFOName.Text := Name;
ParseIFO(Name);
end else if (AnsiCompareFileName(ExtractFileExt(Name), '.LST') = 0) then begin
AssignFile(sl, Name);
Reset(sl);
while (not EoF(sl)) do begin
ReadLn(sl, s);
if ((s <> '') and (s <> Name) and uFileExists(s)) then
AddFile(s);
end;
CloseFile(sl);
Result := True;
end else begin
ignore := False;
s := Name;
while (Pos('\', s) > 0) do
Delete(s, 1, Pos('\', s));
if (Length(s) = 12) then begin
s[5] := 'X'; s[6] := 'X';
if (AnsiCompareFileName(s, 'VTS_XX_0.VOB') = 0) then
ignore := MessageDlg(Format('%s seems to be a Menu VOB...' + #13 + #13 + 'Really add it to the List?', [Name]), mtConfirmation, [mbYes, mbNo], 0) <> mrYes;
end;
if (not ignore) then begin
it := ListViewFiles.Items.Add();
it.Caption := Name;
it.SubItems.Add(IntToStr(((uGetSize(it.Caption) + (1 shl 19)) shr 20)));
end;
end;
end;
end;
procedure TvStripForm.OnVSThreadTerminate(Sender: TObject);
begin
// these are *not* needed anymore, as vs_done was definitely called!
if (data.infile <> nil) then begin
FreeMem(data.infile);
data.infile := nil;
end;
if (cell_list <> nil) then begin
FreeMem(cell_list);
cell_list := nil;
num_cell := 0;
end;
VSThread := nil;
VSThreadActive := False;
ETA.TabVisible := False;
ButtonRun.Caption := '&Run';
ButtonRun.Hint := 'Start Processing';
end;
procedure TvStripForm.WMDropFiles(var m: TMessage);
var
i, j: Cardinal;
buf: array[0..511] of Char;
was_empty, did_list : Boolean;
begin
was_empty := ListViewFiles.Items.Count <= 0;
did_list := False;
j := DragQueryFile(m.WParam, $ffffffff, Nil, 0);
for i := 1 to j do begin
DragQueryFile(m.WParam, i - 1, @buf, SizeOf(buf));
if (AddFile(buf)) then
did_list := True;
end;
if (was_empty and not did_list) then
ListViewFiles.CustomSort(nil, 0);
DragFinish(m.WParam);
end;
function TvStripForm.GetStreamDescription(Idx: Byte; SubStream: Boolean): String;
var
s: String;
begin
s := Format('0x%.2x', [Idx]);
if (SubStream) then
case Idx of
$20..$3f: s := s + ' (Subtitle Stream ' + IntToStr(Idx - $20) + ')';
$80..$87: s := s + ' (AC3 Audio Stream ' + IntToStr(Idx - $80) + ')';
$a0..$a7: s := s + ' (PCM Audio Stream ' + IntToStr(Idx - $a0) + ')';
end
else
case Idx of
$bd: s := s + ' (Private Stream 1)';
$be: s := s + ' (Padding Stream)';
$bf: s := s + ' (Private Stream 2)';
$c0..$c7: s := s + ' (Audio Stream ' + IntToStr(Idx - $c0) + ')';
$e0..$e7: s := s + ' (Video Stream ' + IntToStr(Idx - $e0) + ')';
end;
Result := s;
end;
procedure TvStripForm.ButtonOpenVOBClick(Sender: TObject);
var
i: Integer;
was_empty, did_list: Boolean;
begin
OpenVOBDialog.FileName := '';
if (OpenVOBDialog.Execute()) then with ListViewFiles.Items do begin
SaveInitialDirectory(OpenVOBDialog, vStripRegistryPath, OpenVOBDialog.FileName);
was_empty := Count = 0;
did_list := False;
BeginUpdate();
for i := 0 to OpenVOBDialog.Files.Count - 1 do
if (AddFile(OpenVOBDialog.Files[i])) then
did_list := True;
if (was_empty and not did_list) then
ListViewFiles.CustomSort(nil, 0);
EndUpdate();
end;
end;
procedure TvStripForm.ButtonRemoveVOBClick(Sender: TObject);
var
i: Integer;
begin
ListViewFiles.Items.BeginUpdate();
while (ListViewFiles.SelCount > 0) do
for i := 0 to ListViewFiles.Items.Count - 1 do
if (ListViewFiles.Items[i].Selected) then begin
ListViewFiles.Items.Delete(i);
break;
end;
ListViewFiles.Items.EndUpdate();
end;
procedure TvStripForm.ButtonSortVOBClick(Sender: TObject);
begin
ListViewFiles.CustomSort(nil, 0);
end;
procedure TvStripForm.ButtonUpVOBClick(Sender: TObject);
var
i: Integer;
it: TListItem;
begin
if ((ListViewFiles.SelCount > 0) and not ListViewFiles.Items[0].Selected) then with ListViewFiles.Items do begin
BeginUpdate();
for i := 1 to Count - 1 do
if (ListViewFiles.Items[i].Selected) then begin
it := Insert(i - 1);
it.Caption := ListViewFiles.Items[i + 1].Caption;
it.Selected := ListViewFiles.Items[i + 1].Selected;
it.SubItems.Add(ListViewFiles.Items[i + 1].SubItems[0]);
Delete(i + 1);
end;
EndUpdate();
end;
end;
procedure TvStripForm.ButtonDownVOBClick(Sender: TObject);
var
i: Integer;
it: TListItem;
begin
if ((ListViewFiles.SelCount > 0) and not ListViewFiles.Items[ListViewFiles.Items.Count - 1].Selected) then with ListViewFiles.Items do begin
BeginUpdate();
for i := Count - 2 downto 0 do
if (ListViewFiles.Items[i].Selected) then begin
it := Insert(i + 2);
it.Caption := ListViewFiles.Items[i].Caption;
it.Selected := ListViewFiles.Items[i].Selected;
it.SubItems.Add(ListViewFiles.Items[i].SubItems[0]);
Delete(i);
end;
EndUpdate();
end;
end;
procedure TvStripForm.ButtonOpenIFOClick(Sender: TObject);
begin
OpenIFODialog.FileName := EditIFOName.Text;
if (OpenIFODialog.Execute()) then begin
SaveInitialDirectory(OpenIFODialog, vStripRegistryPath, OpenIFODialog.FileName);
EditIFOName.Text := OpenIFODialog.FileName;
ParseIFO(OpenIFODialog.FileName);
end;
end;
procedure TvStripForm.ListViewFilesCompare(Sender: TObject; Item1,
Item2: TListItem; Data: Integer; var Compare: Integer);
begin
Compare := AnsiCompareFileName(Item1.Caption, Item2.Caption);
end;
procedure TvStripForm.FormCreate(Sender: TObject);
var
i: Integer;
vv, fl: Cardinal;
vv_str: String;
dec_mismatch: Boolean;
begin
// Parse Version Info From DLL
vv := vs_get_version(fl);
vv_str := Format('%u.%u%s', [(vv shr 24) and $ff, (vv shr 16) and $ff, Chr((vv shr 8) and $ff)]);
if ((vv and $ff) > 1) then
vv_str := vv_str + IntToStr(vv and $ff);
if ((fl and vsv_DECRYPT) <> 0) then
vv_str := vv_str + '_css';
vv_str := vv_str + ' by ' + vs_get_author();
Caption := Caption + ' ' + vv_str;
{$IFDEF vs_DECRYPT}
dec_mismatch := True;
{$ELSE}
dec_mismatch := False;
{$ENDIF}
if (dec_mismatch <> ((fl and vsv_DECRYPT) <> 0)) then begin
MessageDlg('Feature/Version Mismatch in ' + vs_DllName + ' and GUI!', mtError, [mbOK], 0);
Application.Terminate();
end;
// Fill the streams in
for i := 0 to 255 do begin
stream_info[i].save := $ff;
stream_info[i].remap_to := i;
stream_info[i + 256].save := $ff;
stream_info[i + 256].remap_to := i;
CheckListBoxStreams.Checked[CheckListBoxStreams.Items.Add(GetStreamDescription(i, False))] := True;
ListBoxRemap.Items.Add(Format('0x%.2x', [i]));
end;
NumIFOChains := 0;
IFOChainIdx := -1;
stream_ofs := 0;
output_mask := $01;
num_cell := 0;
cell_list := nil;
ResetKeepCells := True;
VSThread := nil;
VSThreadActive := False;
ButtonIFOResetClick(nil); // init the cell-list to everything
LoadInitialDirectory(OpenVOBDialog, vStripRegistryPath);
LoadInitialDirectory(OpenIFODialog, vStripRegistryPath);
LoadInitialDirectory(OpenSettingsDialog, vStripRegistryPath);
LoadInitialDirectory(SaveOutputDialog, vStripRegistryPath);
LoadInitialDirectory(SaveSettingsDialog, vStripRegistryPath);
ComboBoxFrameRate.ItemIndex := 0;
ComboBoxAspectRatio.ItemIndex := 0;
ComboBoxASPI.ItemIndex := 0;
{$IFDEF vs_DECRYPT}
ComboBoxKeySearch.ItemIndex := 0;
GroupBoxDecrypt.Visible := True;
{$ENDIF}
num_output := 0;
cur_output := 0;
for i := 0 to inb_MAX_OUTPUT - 1 do begin
outputs[i].FileName := '';
outputs[i].FileSize := 0;
outputs[i].Flags := 0;
end;
PopupMenuItem := Nil;
if (FileExists('vStrip_gui.vsc')) then
LoadSettings('vStrip_gui.vsc');
ButtonUDF.Enabled := aspi_ok;
// parse command-line parameters
for i := 1 to ParamCount() do
AddFile(ParamStr(i));
DragAcceptFiles(Handle, True);
end;
procedure TvStripForm.ButtonRunClick(Sender: TObject);
var
i, j, k, ai: Integer;
total_lba: Int64;
{$IFDEF vs_DECRYPT}
key: Int64;
{$ENDIF}
begin
if ((not VSThreadActive) and (VSThread = nil) and (ListViewFiles.Items.Count > 0)) then begin
VSThreadActive := True;
ETA.TabVisible := True;
data.infile := CreateStreamList(ListViewFiles, total_lba);
GetOutputSettings(outputs[cur_output]);
j := 0;
for i := 0 to num_output do begin
StrLCopy(data.outputs[i].outfile, PChar(outputs[i].FileName), SizeOf(data.outputs[i].outfile));
data.outputs[i].split_output := outputs[i].FileSize;
data.outputs[i].flags := outputs[i].flags;
if (outputs[i].FileName <> '') then
Inc(j);
end;
data.num_outputs := j;
data.flags := vs_SUPPORT_1GB;
data.framerate := $ffffffff;
if (ComboBoxFrameRate.ItemIndex > 0) then
data.framerate := ComboBoxFrameRate.ItemIndex;
data.aspectratio := $ffffffff;
if (ComboBoxAspectRatio.ItemIndex > 0) then
data.aspectratio := ComboBoxAspectRatio.ItemIndex;
if (not CheckBoxISVOB.Checked) then
data.flags := data.flags + vs_NO_VOB;
if (CheckBoxDemacro.Checked) then
data.flags := data.flags + vs_DEMACRO;
case ComboBoxASPI.ItemIndex of
0: data.flags := data.flags + vs_USE_ASPI;
1: data.flags := data.flags + vs_USE_ASPI + vs_PREFER_ASPI;
end;
ParseCardinal(EditMaxSync.Text, 2048, data.max_sync_bytes);
ParseCardinal(EditStartLBA.Text, 0, data.start_lba);
ParseCardinal(EditEndLBA.Text, $ffffffff, data.end_lba);
{$IFDEF vs_DECRYPT}
ParseCardinal(EditSameGuess.Text, 2, data.same_guess);
ParseCardinal(EditPadGuess.Text, 2, data.pad_guess);
ParseCardinal(EditPercentageGuess.Text, 75, data.pc_guess);
data.key[0] := 0;
data.key[1] := 0;
data.key[2] := 0;
data.key[3] := 0;
data.key[4] := 0;
if ((EditKey.Text <> '') and (Length(EditKey.Text) = 10)) then begin
key := StrToInt64('$' + EditKey.Text);
data.key[0] := key shr 32;
data.key[1] := (key shr 24) and $ff;
data.key[2] := (key shr 16) and $ff;
data.key[3] := (key shr 8) and $ff;
data.key[4] := key and $ff;
end;
case ComboBoxKeySearch.ItemIndex of
1: data.flags := data.flags + vs_CRACK_EACH_VOB_ID;
2: data.flags := data.flags + vs_CRACK_EACH_CELL_ID;
3: data.flags := data.flags + vs_CRACK_EACH_VOB_ID + vs_CRACK_EACH_CELL_ID;
4: data.flags := data.flags + vs_DONT_CRACK;
end;
{$ENDIF}
ai := 1;
if (IFOChainIdx <> -1) then begin
if (RadioGroupAngles.Enabled) then begin
if (RadioGroupAngles.ItemIndex = RadioGroupAngles.Items.Count - 1) then
ai := 0 // all angles
else
ai := 1 + RadioGroupAngles.ItemIndex;
end;
end;
k := 0;
for i := 0 to 255 do
for j := 0 to 255 do
if (KeepCells[i, j, 0] and KeepCells[i, j, 1]) then
Inc(k);
if ((k <> 256 * 256) and (k <> 0)) then begin
num_cell := k;
GetMem(cell_list, num_cell * SizeOf(t_vs_vobcellid));
k := 0;
if (IFOChainIdx <> -1) then begin
for i := 0 to IFOChains[IFOChainIdx].NumCells - 1 do with IFOChains[IFOChainIdx].Cells[i] do
if (KeepCells[vob_id and $ff, cell_id, 0] and KeepCells[vob_id and $ff, cell_id, 1]) then begin
cell_list^[k].vob_id := vob_id;
cell_list^[k].cell_id := cell_id;
cell_list^[k].angle := angle;
Inc(k);
end;
num_cell := k;
if (ai <> 0) then
for i := 0 to num_cell - 1 do
if (((cell_list^[i].angle shr 4) >= ai) and ((cell_list^[i].angle and $f) <> ai)) then begin
cell_list^[i].vob_id := 0;
cell_list^[i].cell_id := 0;
end;
end else begin
for i := 0 to 255 do
for j := 0 to 255 do
if (KeepCells[i, j, 0] and KeepCells[i, j, 1]) then begin
cell_list^[k].vob_id := i;
cell_list^[k].cell_id := j;
Inc(k);
end;
end;
end;
for i := 0 to 255 do begin
streams[i].remap_to := stream_info[i].remap_to;
streams[i].user_func := 0;
streams[i].save := stream_info[i].save;
substreams[i].remap_to := stream_info[i + 256].remap_to;
substreams[i].user_func := 0;
substreams[i].save := stream_info[i + 256].save;
end;
ButtonRun.Caption := '&Abort';
ButtonRun.Hint := 'Abort Processing';
VSThread := TVSThread.CreateVS(@data, @streams, @substreams, total_lba, num_cell, cell_list, ProgressBar1, ListViewInfo, ListViewFiles);
VSThread.OnTerminate := OnVSThreadTerminate;
VSThread.Suspended := False;
end else if ((VSThread <> nil) and VSThreadActive) then
VSThread.Terminate();
end;
procedure TvStripForm.FormDestroy(Sender: TObject);
var
i: Integer;
begin
if ((VSThread <> nil) and VSThreadActive) then begin
VSThread.Terminate();
VSThread.WaitFor();
end;
for i := 0 to NumIFOChains - 1 do
if (IFOChains[i].Cells <> NiL) then begin
FreeMem(IFOChains[i].Cells);
IFOChains[i].Cells := Nil;
end;
SetLength(IFOChains, 0);
NumIFOChains := 0;
end;
procedure TvStripForm.ButtonClearVOBClick(Sender: TObject);
begin
ListViewFiles.Items.Clear();
EditStartLBA.Text := '';
EditEndLBA.Text := '';
EditKey.Text := '';
end;
procedure TvStripForm.ListBoxRemapClick(Sender: TObject);
begin
if ((ListBoxRemap.ItemIndex <> -1) and (CheckListBoxStreams.ItemIndex <> -1)) then
stream_info[stream_ofs + CheckListBoxStreams.ItemIndex].remap_to := ListBoxRemap.ItemIndex;
end;
procedure TvStripForm.CheckBoxSubstreamsClick(Sender: TObject);
var
i: Integer;
new_ofs: Integer;
begin
if (CheckBoxSubstreams.Checked) then begin
new_ofs := 256;
GroupBoxStreams.Caption := 'SubStreams:'
end else begin
new_ofs := 0;
GroupBoxStreams.Caption := 'Streams:'
end;
if (new_ofs <> stream_ofs) then begin
for i := 0 to 255 do begin
CheckListBoxStreams.Checked[i] := (stream_info[i + new_ofs].save and output_mask) <> 0;
CheckListBoxStreams.Items.Strings[i] := GetStreamDescription(i, CheckBoxSubstreams.Checked);
end;
CheckListBoxStreams.ItemIndex := -1;
ListBoxRemap.ItemIndex := -1;
stream_ofs := new_ofs;
end;
end;
procedure TvStripForm.ButtonAllStreamsClick(Sender: TObject);
var
i: Integer;
begin
for i := 0 to 255 do begin
stream_info[i].save := stream_info[i].save or output_mask;
stream_info[i + 256].save := stream_info[i + 256].save or output_mask;
CheckListBoxStreams.Checked[i] := True;
end;
end;
procedure TvStripForm.ButtonNoStreamsClick(Sender: TObject);
var
i: Integer;
begin
for i := 0 to 255 do begin
stream_info[i].save := stream_info[i].save and (not output_mask);
stream_info[i + 256].save := stream_info[i + 256].save and (not output_mask);
CheckListBoxStreams.Checked[i] := False;
end;
end;
procedure TvStripForm.CheckBoxDemuxClick(Sender: TObject);
var
i, j: Integer;
begin
CheckBoxAC3Header.Enabled := CheckBoxDemux.Checked;
CheckBoxPCMHeader.Enabled := CheckBoxDemux.Checked;
ListBoxRemap.Enabled := not CheckBoxDemux.Checked and (RadioGroupOutputs.ItemIndex = 0);
LabelRemap.Enabled := not CheckBoxDemux.Checked and (RadioGroupOutputs.ItemIndex = 0);
ButtonAllStreams.Enabled := not CheckBoxDemux.Checked and (RadioGroupOutputs.ItemIndex = 0);
j := 0;
if (CheckBoxDemux.Checked) then begin
for i := 0 to 511 do
if ((stream_info[i].save and output_mask) <> 0) then
Inc(j);
if (j > 1) then
ButtonNoStreamsClick(Sender); // select none, if more than 1 selected
end;
end;
procedure TvStripForm.EditFileSizeKeyPress(Sender: TObject; var Key: Char);
begin
if ((Key > #31) and not (Key in ['0'..'9'])) then
Key := #0;
end;
procedure TvStripForm.ButtonOutputClick(Sender: TObject);
begin
SaveOutputDialog.FileName := EditFileName.Text;
if (SaveOutputDialog.Execute()) then begin
EditFileName.Text := SaveOutputDialog.FileName;
UpdateFileName(EditFileName.Text, RadioGroupOutputs, cur_output, num_output);
SaveInitialDirectory(SaveOutputDialog, vStripRegistryPath, SaveOutputDialog.FileName);
end;
end;
procedure TvStripForm.EditKeyKeyPress(Sender: TObject; var Key: Char);
begin
if ((Key > #31) and not (UpCase(Key) in ['0'..'9','A'..'F'])) then
Key := #0;
end;
procedure TvStripForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
if ((VSThread <> nil) and VSThreadActive) then begin
if (MessageDlg('Operation in Progress...' + #13 + #13 + 'Quit?', mtConfirmation, [mbYes, mbNo], 0) <> mrYes) then
CanClose := False;
end;
end;
procedure TvStripForm.ButtonIFOResetClick(Sender: TObject);
var
i, j: Integer;
begin
for i := 0 to NumIFOChains - 1 do
if (IFOChains[i].Cells <> Nil) then begin
FreeMem(IFOChains[i].Cells);
IFOChains[i].Cells := Nil;
end;
SetLength(IFOChains, 0);
IFOChainIdx := -1;
NumIFOChains := 0;
RadioGroupAngles.Items.Clear();
TreeViewIFO.Items.Clear();
ListBoxIFOAudio.Items.Clear();
ListBoxIFOSub.Items.Clear();
ListBoxVOBID.Items.Clear();
CheckListBoxCellID.Items.Clear();
for i := 0 to 255 do begin
for j := 0 to 255 do begin
KeepCells[i, j, 0] := True;
KeepCells[i, j, 1] := True;
end;
ListBoxVOBID.Items.Add(Format('%.3u', [i]));
CheckListBoxCellID.Items.Add(Format('%.3u', [i]));
CheckListBoxCellID.Checked[i] := True;
end;
ListBoxVOBID.ItemIndex := 0;
end;
procedure TvStripForm.ListBoxVOBIDClick(Sender: TObject);
var
idx, i, j: Integer;
begin
if (ListBoxVobID.ItemIndex <> -1) then begin
Val(ListBoxVobID.Items[ListBoxVobID.ItemIndex], idx, i);
if (i = 0) then begin
CheckListBoxCellID.Items.Clear();
j := 0;
for i := 0 to 255 do
if (KeepCells[idx, i, 0]) then begin
CheckListBoxCellID.Items.Add(Format('%.3u', [i]));
CheckListBoxCellID.Checked[j] := KeepCells[idx, i, 1];
Inc(j);
end;
end;
end;
end;
procedure TvStripForm.CheckListBoxCELLIDClickCheck(Sender: TObject);
var
i, j, k: Integer;
begin
if ((CheckListBoxCellID.ItemIndex <> -1) and (ListBoxVobID.ItemIndex <> -1)) then begin
Val(ListBoxVobID.Items[ListBoxVobID.ItemIndex], i, k);
if (k = 0) then begin
Val(CheckListBoxCellID.Items[CheckListBoxCellID.ItemIndex], j, k);
if (k = 0) then
KeepCells[i, j, 1] := CheckListBoxCellID.Checked[CheckListBoxCellID.ItemIndex];
end;
end;
end;
procedure TvStripForm.TreeViewIFOChange(Sender: TObject; Node: TTreeNode);
var
it: TTreeNode;
i, j, k, max_a: Integer;
arr: array[0..255] of Boolean;
begin
if (NumIFOChains > 0) then begin
it := Node;
while (it.Parent <> nil) do
it := it.Parent;
if (IFOChainIdx <> Integer(it.Data)) then begin
IFOChainIdx := Integer(it.Data);
max_a := 0;
for i := 0 to IFOChains[IFOChainIdx].NumCells - 1 do with IFOChains[IFOChainIdx].Cells[i] do
max_a := Max(max_a, angle and $f);
RadioGroupAngles.Enabled := max_a > 1;
RadioGroupAngles.Items.Clear();
for i := 0 to max_a - 1 do
RadioGroupAngles.Items.Add('Angle ' + IntToStr(i + 1));
RadioGroupAngles.ItemIndex := 0;
RadioGroupAngles.Items.Add('All');
// Update VOB/CELL-Lists
ListBoxVOBID.Items.Clear();
for i := 0 to 255 do
arr[i] := False;
for i := 0 to IFOChains[IFOChainIdx].NumCells - 1 do with IFOChains[IFOChainIdx].Cells[i] do
arr[vob_id and $ff] := True;
for i := 0 to 255 do
if (arr[i]) then
ListBoxVobID.Items.Add(Format('%.3u', [i]));
for i := 0 to 255 do
for j := 0 to 255 do begin
KeepCells[i, j, 0] := False;
if (ResetKeepCells) then
KeepCells[i, j, 1] := False;
end;
for i := 0 to IFOChains[IFOChainIdx].NumCells - 1 do with IFOChains[IFOChainIdx].Cells[i] do begin
KeepCells[vob_id and $ff, cell_id, 0] := True;
if (ResetKeepCells) then
KeepCells[vob_id and $ff, cell_id, 1] := True;
end;
if (Node.Parent = nil) then begin
ListBoxVobID.ItemIndex := 0;
ListBoxVOBIDClick(nil);
end;
end;
if (Node.Parent <> nil) then begin // follow idx
i := Integer(Node.Data);
with IFOChains[IFOChainIdx].Cells[i] do begin
for j := 0 to ListBoxVobID.Items.Count - 1 do begin
Val(ListBoxVobID.Items[j], k, max_a);
if ((max_a = 0) and (vob_id = k)) then
if (ListBoxVobID.ItemIndex <> j) then begin
ListBoxVobID.ItemIndex := j;
ListBoxVOBIDClick(nil);
break;
end;
end;
for j := 0 to CheckListBoxCellID.Items.Count - 1 do begin
Val(CheckListBoxCellID.Items[j], k, max_a);
if ((max_a = 0) and (cell_id = k)) then begin
CheckListBoxCellID.ItemIndex := j;
break;
end;
end;
end;
end;
end;
end;
procedure TvStripForm.CheckListBoxStreamsClick(Sender: TObject);
begin
if (CheckListBoxStreams.ItemIndex <> -1) then begin
ListBoxRemap.ItemIndex := stream_info[stream_ofs + CheckListBoxStreams.ItemIndex].remap_to;
if (CheckListBoxStreams.Checked[CheckListBoxStreams.ItemIndex]) then
stream_info[stream_ofs + CheckListBoxStreams.ItemIndex].save := stream_info[stream_ofs + CheckListBoxStreams.ItemIndex].save or output_mask
else
stream_info[stream_ofs + CheckListBoxStreams.ItemIndex].save := stream_info[stream_ofs + CheckListBoxStreams.ItemIndex].save and (not output_mask);
end;
end;
procedure TvStripForm.ButtonSaveSettingsClick(Sender: TObject);
begin
if (SaveSettingsDialog.Execute()) then begin
SaveInitialDirectory(SaveSettingsDialog, vStripRegistryPath, SaveSettingsDialog.FileName);
SaveSettings(SaveSettingsDialog.FileName);
end;
end;
procedure TvStripForm.ButtonLoadSettingsClick(Sender: TObject);
begin
if (OpenSettingsDialog.Execute()) then begin
SaveInitialDirectory(OpenSettingsDialog, vStripRegistryPath, OpenSettingsDialog.FileName);
LoadSettings(OpenSettingsDialog.FileName);
end;
end;
procedure TvStripForm.EditFileNameChange(Sender: TObject);
begin
if (EditFileName.Modified) then
UpdateFileName(EditFileName.Text, RadioGroupOutputs, cur_output, num_output);
end;
procedure TvStripForm.RadioGroupOutputsClick(Sender: TObject);
var
i: Integer;
begin
GetOutputSettings(outputs[cur_output]);
cur_output := RadioGroupOutputs.ItemIndex;
PutOutputSettings(outputs[cur_output]);
output_mask := 1 shl RadioGroupOutputs.ItemIndex;
if (output_mask = $01) then begin
LabelRemap.Enabled := not CheckBoxDemux.Checked;
ListBoxRemap.Enabled := not CheckBoxDemux.Checked;
end else begin
LabelRemap.Enabled := False;
ListBoxRemap.Enabled := False;
end;
for i := 0 to 255 do
CheckListBoxStreams.Checked[i] := (stream_info[i + stream_ofs].save and output_mask) <> 0;
end;
procedure TvStripForm.TreeViewIFOContextPopup(Sender: TObject; MousePos: TPoint;
var Handled: Boolean);
var
it: TTreeNode;
begin
if ((MousePos.x <> -1) and (MousePos.y <> - 1)) then
it := TreeViewIFO.GetNodeAt(MousePos.x, MousePos.y)
else
it := TreeViewIFO.Selected;
if (it <> Nil) then begin
PopupMenuIFO.Items[0].Enabled := True;
PopupMenuIFO.Items[1].Enabled := True;
PopupMenuIFO.Items[2].Enabled := True;
PopupMenuItem := it;
end else begin
PopupMenuIFO.Items[0].Enabled := False;
PopupMenuIFO.Items[1].Enabled := False;
PopupMenuIFO.Items[2].Enabled := False;
PopupMenuItem := Nil;
end;
end;
procedure TvStripForm.SetStartLBAClick(Sender: TObject);
var
i, j: Integer;
Top: TTreeNode;
begin
if (PopupMenuItem <> Nil) then begin
if (PopupMenuItem.Parent <> Nil) then begin
Top := PopupMenuItem.Parent;
while (Top.Parent <> Nil) do
Top := Top.Parent;
i := Integer(Top.Data);
j := Integer(PopupMenuItem.Data);
if ((i < NumIFOChains) and (j < IFOChains[i].NumCells)) then
EditStartLBA.Text := IntToStr(IFOChains[i].Cells[j].start_lba);
end else begin
i := Integer(PopupMenuItem.Data);
if ((i < NumIFOChains) and (IFOChains[i].NumCells > 0)) then
EditStartLBA.Text := IntToStr(IFOChains[i].Cells[0].start_lba);
end;
end;
end;
procedure TvStripForm.SetEndLBAClick(Sender: TObject);
var
i, j, k: Integer;
Top: TTreeNode;
begin
if (PopupMenuItem <> Nil) then begin
if (PopupMenuItem.Parent <> Nil) then begin
Top := PopupMenuItem.Parent;
while (Top.Parent <> Nil) do
Top := Top.Parent;
i := Integer(Top.Data);
j := Integer(PopupMenuItem.Data);
if ((i < NumIFOChains) and (j < IFOChains[i].NumCells)) then begin
if (PopupMenuItem.Parent.Parent = Nil) then begin // Chapter
k := j;
while ((k < IFOChains[i].NumCells) and (IFOChains[i].Cells[j].chapter = IFOChains[i].Cells[k].chapter)) do
Inc(k);
EditEndLBA.Text := IntToStr(IFOChains[i].Cells[k - 1].end_lba); // Chapter End
end else
EditEndLBA.Text := IntToStr(IFOChains[i].Cells[j].end_lba); // Cell
end;
end else begin
i := Integer(PopupMenuItem.Data);
if ((i < NumIFOChains) and (IFOChains[i].NumCells > 0)) then
EditEndLBA.Text := IntToStr(IFOChains[i].Cells[IFOChains[i].NumCells - 1].end_lba);
end;
end;
end;
procedure TvStripForm.ButtonUDFClick(Sender: TObject);
var
udf_sel: TUDFSelector;
i: Integer;
begin
udf_sel := TUDFSelector.Create(vStripForm);
udf_sel.ShowModal();
if (udf_sel.ModalResult > 0) then begin
for i := 0 to udf_sel.ListBoxFiles.Items.Count - 1 do
AddFile(udf_sel.ListBoxFiles.Items[i]);
end;
udf_sel.Free();
end;
procedure TvStripForm.SetStartEndLBAClick(Sender: TObject);
begin
SetStartLBAClick(Sender);
SetEndLBAClick(Sender);
end;
procedure TvStripForm.CheckBoxKeepGOPsClick(Sender: TObject);
begin
CheckBoxDVD2AVI.Enabled := not CheckBoxKeepGOPs.Checked;
end;
end.
syntax highlighted by Code2HTML, v. 0.9.1